Я не могу обновить созданный ранее объект. Я получаю исключение StaleObjectException
с сообщением:
Row was updated or deleted by another transaction (or unsaved-value mapping was incorrect): [Project.DomainLayer.Entities.Employee#00000000-0000-0000-0000-000000000000]
Я не передаю процесс обновления никому. В чем проблема?
Доступ к данным /DI
public class DataAccessModule : Ninject.Modules.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();
}
}
Доступ к данным/сопоставления
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" assembly="Project.DomainLayer" namespace="Project.DomainLayer.Entities">
<class name="Employee" optimistic-lock="version">
<id name="ID" column="EmployeeID" unsaved-value="00000000-0000-0000-0000-000000000000">
<generator class="guid.comb" />
</id>
<version name="Version" type="Int32" column="Version" />
<!-- properties -->
<property name="EmployeeNumber" />
<!-- ... -->
<property name="PassportRegistredOn" not-null="true" />
<!-- sets -->
<set name="AttachedInformation" cascade="all">
<key column="EmployeeID" />
<element column="Attachment" />
</set>
<set name="TravelVouchers" cascade="all">
<key column="EmployeeID" />
<one-to-many class="TravelVoucher" />
</set>
</class>
</hibernate-mapping>
Доступ к данным/репозиторий
public class Repository<T> : IRepository<T> where T : AbstractEntity<T>, IAggregateRoot
{
private ISession session;
public Repository(ISession session)
{
this.session = session;
}
// other methods are omitted
public void Update(T entity)
{
using(var transaction = this.session.BeginTransaction())
{
this.session.Update(entity);
transaction.Commit();
}
}
public void Update(Guid id)
{
using(var transaction = this.session.BeginTransaction())
{
this.session.Update(this.session.Load<T>(id));
transaction.Commit();
}
}
}
Внутри контроллера
public class EmployeeController : Controller
{
private IRepository<Employee> repository;
public EmployeeController(IRepository<Employee> repository)
{
this.repository = repository;
}
public ActionResult Edit(Guid id)
{
var e = repository.Load(id);
return View(e);
}
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Edit(Employee employee)
{
if(ModelState.IsValid)
{
repository.Update(employee);
return RedirectToAction("Deatils", "Employee", new { id = employee.ID });
}
else
{
return View(employee);
}
}
}
Как обновить объекты? Спасибо!
ИЗМЕНИТЬ
Итак, я добавил unsaved-value="{Guid.Empty goes here}"
в свою разметку. Более того, я попытался сделать следующее:
public void Update(T entity)
{
using(var transaction = this.session.BeginTransaction())
{
try
{
this.session.Update(entity);
transaction.Commit();
}
catch(StaleObjectStateException ex)
{
try
{
session.Merge(entity);
transaction.Commit();
}
catch
{
transaction.Rollback();
throw;
}
}
}
}
И это дает мне тот же эффект. Я имею в виду transaction.Commit();
после того, как Merge
дает то же исключение.
Также мне интересно, следует ли открывать, используя скрытый ввод, объект ID
в представлении Edit
?
ИЗМЕНИТЬ
Таким образом, сущность действительно отделяется. Когда он переходит к контроллеру, ID
равен Guid.Empty
. Как мне обрабатывать, Merge
или Reattach
?