在我的asp.net mvc应用程序中,我有一个Log对象,用于跟踪论坛中发生的事情。在事务中添加注释时,会发生以下情况:
新提交的评论会添加到提交表
一个新的日志条目与该评论的id一起被添加到日志表中
最后提交事务并且不生成异常。但事实证明,当提交事务时,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;
}
}
答案 0 :(得分:0)
当然,当您尝试在单个事务中添加注释和日志条目时,尚未生成Comment
的ID,除非您使用“手动ID分配”方法或刷新会话以保持更改你做了。
在您的原始帖子中,添加评论后您没有“刷新”,并且您想要添加该评论的日志(尚未定义ID)。
不确定为什么Nhibernate会采用如此相反的顺序但看起来至少是ID生成问题。
引起我注意的另一件事是你并排使用Comment
和Args.Comment
。有什么区别?
无论如何,如果Comment
在某种程度上是您的域名实体,则必须:
ISession
(您应该有会话附加的Comment
实体对象可用);