为什么NHibernate会抛出“StaleObjectStateException”异常?

7

我正在撰写一个项目,并使用 NHibernate 3.1。

SimpleTest:

Forum forum = Session.CreateCriteria<Forum>().Add(Restrictions.Eq("UrlName", "reportabug")).UniqueResult<Forum>();
forum.TopicsCount++;
IForumRepository forumRepository = new ForumRepository(SessionFactory);
forumRepository.Update(forum);

public virtual void Update(TEntity entity)
{
    if (!session.Transaction.IsActive)
    {
        TResult result;
        using (var tx = session.BeginTransaction())
        {
            session.SaveOrUpdate(entity)
            tx.Commit();
        }
        return result;
    }
    session.SaveOrUpdate(entity)
}

最近的更新抛出了异常:
StaleObjectStateException was unhandled by user code:
    Row was updated or deleted by another transaction (or unsaved-value mapping was incorrect)

SQL查询:

UPDATE Forums
SET    Name = 'Forums Issues (not product support)' /* @p0 */,
       UrlName = 'reportabug' /* @p1 */,
       Description = 'Use this forum to report issues with the online forums application. When reporting an issue please include relevant details such as repro steps, error messages and browser version.' /* @p2 */,
       CategoryId = 'b2cc232c-0d5c-4f35-bb6f-29c67d7d40c2' /* @p3 */,
       TopicsCount = 1 /* @p4 */
WHERE  ForumId = '864046b7-ca57-48c4-8a81-082103223527' /* @p5 */

论坛ID是正确的。 可能是并发问题吗? 有什么想法吗?


@ManuPK,异常抛出在tx.Commit()这一行。 - Kovpaev Alexey
1个回答

10

StaleObjectStateException是Hibernate确保数据一致性的一种方式,可以在此处阅读API 传送门。Hibernate维护它更新的对象的版本,如果数据库中的版本和内存中的版本不匹配,则会抛出错误。在这里了解更多有关乐观锁定机制的信息传送门

因此,请使用此信息调试应用程序。我对C#语法不熟悉,但我认为第二个保存应该在else条件中。


没错,我完全忽略了那个:P +1。@Kovpaev - 删除最后一个session.SaveOrUpdate(entity),不需要它。 - Ash Burlaczenko
@Ash Burlaczenko,如果在外部事务的上下文中调用Update()方法,则需要在方法末尾进行调用。如果不是,则在“if”块中创建它。 - Kovpaev Alexey

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接