Steven Suryana
Steven Suryana

Reputation: 179

Using Session.Flush then ITransaction.Commit makes data rollback

I'm trying to update an entity using Session.Update then continue to execute another SQL query. The other query did not see the changed value. When i traced it using profiler, Session.Update did nothing.

public class InvoiceService()
{
    public void Update(Invoice invoice)
    {
        using (var trans = BeginTransaction())
        {
            Session.Update(invoice); //Nhibernate did not update invoice. 

            ExecuteNamedQuery(); //Query executed before invoice updated.

            trans.Commit(); //Invoice updated.
        }
    }
}

Then i add Session.Flush after Session.Update.

using (var trans = BeginTransaction())
{
    Session.Update(invoice);
    Session.Flush()

    ExecuteNamedQuery();

    trans.Commit();
}

After Session.Flush executed, SQL query for update is executed also. It works perfectly. The execution order is correct. But then i executed another method to get all invoices. Committing transaction makes nhibernate execute update query to update my updated invoice earlier with old values. (ex: Quantity = 20, updated to 10, then updated again to 20)

public void FindAll()
{
    using (var trans = BeginTransaction())
    {
        var invoices = Session.CreateCriteria<Invoice>().List<Invoice>();

        trans.Commit(); // In here invoice that i updated earlier get updated again, using old values.

        return invoices;
    }
}

Why it's getting updated again?

What's the solution for this problem?

Thanks in advance.

Upvotes: 0

Views: 162

Answers (1)

Jamie Ide
Jamie Ide

Reputation: 49301

Update is an unfortunate name for the method; the purpose of Update is to attach a transient instance to a new session. See the documentation for update and make sure you understand instance states.

The invoice is updated to the original values because NHibernate thinks it has changed. This "phantom" update may be caused by a property changing unexpectedly. A typical root cause is a nullable database column mapped to a non-nullable property (or vice-versa). The easiest way to troubleshoot is to turn on dynamic-update in the session factory configuration so that you can see which properties NHibernate detects as dirty.

Upvotes: 3

Related Questions