Note that there are some explanatory texts on larger screens.

plurals
  1. POWhy is NHibernate persisting new objects in the wrong order of creation even inside a transaction?
    text
    copied!<p>In my asp.net mvc app I have a Log object which tracks what happens in my forum. when a comment is added inside a transaction the following happens:</p> <ol> <li><p>A new comment is added to the submissions table</p></li> <li><p>A new log entry with a reference to the id of that comment is added to the logs table</p></li> </ol> <p>Finally the transaction is committed and no exceptions are generated. But it turns out that when the transaction is committed, NHibernate first inserts the Log record and then the Comment record, therefore saving the log record with an incorrect comment id which is 0.</p> <p>Here is some code to show what is happening:</p> <pre><code>using (IAtomicTransaction Transaction = UnitOfWork.BeginTransaction()) { try { SubmissionRepository.AddComment(Comment, ParentSubmission); LogRepository.AddCommentEntry(Comment); Transaction.Commit(); } catch { Transaction.Rollback(); throw; } } </code></pre> <p>UnitOfWork and AtomicTransaction are just wrappers around the ISession and ITransaction objects from the NHibernate APIs. And here is the log generated which confirms the problem:</p> <pre><code>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() </code></pre> <p>What is the solution to this problem?</p> <h2>Update:</h2> <p>So it turned out that if I call Flush after every insert then the order will be correct.</p> <pre><code>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; } } </code></pre>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload