我有一個相當直接的映射:由於空版本列而無法保存實體。 NHibernate的
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" assembly="XXXX.DomainLayer" namespace="XXXX.DomainLayer.Entities">
<class name="Project" optimistic-lock="version">
<id name="Id" column="ProjectID" unsaved-value="00000000-0000-0000-0000-000000000000">
<generator class="guid.comb" />
</id>
<version name="Version" generated="always" type="BinaryBlob" />
<!-- poperties -->
</class>
</hibernate-mapping>
和相應的實體如下:
public abstract class AbstractEntity<T> where T : AbstractEntity<T> {
public virtual Guid Id { get; protected set; }
public virtual Byte[] Version { get; set; }
// other properties, methods
}
public class Project : AbstractEntity<Project>, IAggregateRoot {
// specific properties, methods
}
我出口的模式來SqlServer
。那裏一切都很好。但每次我發佈表單時(create action
)SqlServer
拋出一個美國例外:
無法插入NULL值插入「版本」列...
所以insert
得到恢復。
最初的問題就解決了
實際的問題是,我不能讓編輯過的實體 - 我越來越StaleObjectStateException
。
行被另一事務更新或刪除(或者未保存值的映射是不正確的)[XXXX.DomainLayer.Entities.Project#707991d0-07b5-45fc-99ed-a0cc00db108a]
檢查當在SQLServer
很顯然,無論如何版本列都保持爲空。
控制器代碼
public ActionResult Create() {
return View("Edit", new EditProjectViewModel());
}
[HttpGet]
public ActionResult Edit(Guid id) {
var project = this.repo.Get(id);
var model = Mapper.Map<Project, EditProjectViewModel>(project);
return View(model);
}
[HttpPost, ValidateAntiForgeryToken]
public ActionResult Edit(EditProjectViewModel model) {
if(ModelState.IsValid) {
model.InitiatedBy = this.userService.GetUser(some_param);
model.ProblemContext = BBCode.ToHtml(model.ProblemContext);
var project = Mapper.Map<EditProjectViewModel, Project>(model);
if(project.IsTransient) {
this.repo.Add(project);
}
else {
try {
this.repo.Update(project);
}
catch(NHibernate.StaleObjectStateException e) {
// Some logic here
}
}
return RedirectToAction("Index", "Home", new { area = "" });
} // if(ModelState.IsValid) {
return View(model);
}
凡庫Update
方法是這樣的:
public void Update(T entity) {
using(var tx = this.session.BeginTransaction()) {
/* try { */
this.session.SaveOrUpdate(entity);
tx.Commit();
/* }
catch(StaleObjectStateException) {
try {
entity = this.session.Merge(entity);
tx.Commit();
}
catch(Exception) {
tx.Rollback();
throw;
}
}
*/
}
}
DI件
public class DataAccessModule : NinjectModule {
public override void Load() {
this.Bind<ISessionFactory>()
.ToMethod(c => new Configuration().Configure().BuildSessionFactory())
.InSingletonScope();
this.Bind<ISession>()
.ToMethod(ctx => ctx.Kernel.TryGet<ISessionFactory>().OpenSession())
.InRequestScope();
this.Bind(typeof(IRepository<>)).To(typeof(Repository<>))
.InRequestScope();
}
}
謝謝!
您是否嘗試將「sql-type」設置爲「timestamp」和「unsaved-value」爲「null」(請參閱我的答案)? – Alexander