为什么NHibernate甚至在事务内部以错误的创建顺序持久化新对象?

时间:2011-02-09 04:06:25

标签: asp.net-mvc nhibernate hibernate fluent-nhibernate nhibernate-mapping

在我的asp.net mvc应用程序中,我有一个Log对象,用于跟踪论坛中发生的事情。在事务中添加注释时,会发生以下情况:

  1. 新提交的评论会添加到提交表

  2. 一个新的日志条目与该评论的id一起被添加到日志表中

  3. 最后提交事务并且不生成异常。但事实证明,当提交事务时,NHibernate首先插入日志记录然后插入注释记录,因此使用不正确的注释ID保存日志记录,该记录为0。

    以下是一些显示正在发生的事情的代码:

    using (IAtomicTransaction Transaction = UnitOfWork.BeginTransaction())
    {
        try
        {
            SubmissionRepository.AddComment(Comment, ParentSubmission);
            LogRepository.AddCommentEntry(Comment);            
    
            Transaction.Commit();
        }
        catch
        {
            Transaction.Rollback();
            throw;
        }
    }
    

    UnitOfWork和AtomicTransaction只是来自NHibernate API的ISession和ITransaction对象的包装器。这是生成的日志,用于确认问题:

    2011-02-09 14:42:05,631 [15] DEBUG NHibernate.SQL - INSERT INTO logs (version, created_at, updated_at, comment_id) VALUES (?p0, ?p1, ?p2, ?p3); ?p0 = 9/02/2011 2:42:05 PM, ?p1 = 9/02/2011 3:41:52 AM, ?p2 = NULL, ?p3 = 0
    2011-02-09 14:42:05,647 [15] DEBUG NHibernate.SQL - SELECT LAST_INSERT_ID()
    2011-02-09 14:42:05,647 [15] DEBUG NHibernate.SQL - INSERT INTO submissions (version, created_at, updated_at, body) VALUES (?p0, ?p1, ?p2, ?p3);?p0 = 9/02/2011 2:42:05 PM, ?p1 = 9/02/2011 3:41:52 AM, ?p2 = 9/02/2011 3:41:52 AM, ?p3 = 'dfgdfgd dfg df'
    2011-02-09 14:42:05,647 [15] DEBUG NHibernate.SQL - SELECT LAST_INSERT_ID()
    

    这个问题的解决方案是什么?

    更新

    事实证明,如果我在每次插入后调用Flush,那么订单将是正确的。

    using (IAtomicTransaction Transaction = UnitOfWork.BeginTransaction())
    {
        try
        {
            SubmissionRepository.AddComment(Comment, ParentSubmission);
            UnitOfWork.CurrentSession.Flush();
    
            LogRepository.AddCommentEntry(Comment);            
            UnitOfWork.CurrentSession.Flush();
    
            Transaction.Commit();
        }
        catch
        {
            Transaction.Rollback();
            throw;
        }
    }
    

1 个答案:

答案 0 :(得分:0)

当然,当您尝试在单个事务中添加注释和日志条目时,尚未生成Comment的ID,除非您使用“手动ID分配”方法或刷新会话以保持更改你做了。

在您的原始帖子中,添加评论后您没有“刷新”,并且您想要添加该评论的日志(尚未定义ID)。

不确定为什么Nhibernate会采用如此相反的顺序但看起来至少是ID生成问题。

引起我注意的另一件事是你并排使用CommentArgs.Comment。有什么区别?

无论如何,如果Comment在某种程度上是您的域名实体,则必须:

  • 插入;
  • 确保它已附加到当前ISession (您应该有会话附加的Comment实体对象可用);
  • 使用该实体(已在存储库中)进行日志输入(NHibernate将处理关系)。