Good ideas for debugging Hibernate Session/Transaction errors?

6.8k views Asked by At

I've used Hibernate for a little while now and have become accustomed to most of the common error messages. Most point me straight to the problem, but I've been having issues with this one:

org.hibernate.NonUniqueObjectException: a different object with the same identifier value was already associated with the session

I understand the error (the session has two different objects with the same ID), but I don't really know of a good way to debug my code to find the source of the issue. Usually, I look at the code that I'm currently changing and look for places where I load one object and manually create another, hoping that I can find a simple error in my logic. However, I'm currently working with a code set that I didn't write, that am not familiar with, and that has no documentation. The only solution that I can think of is to go through the code, line by line, hoping to find the error. Do you know of a better way to debug this error?

Additionally, the exact error that I'm getting is from a call to saveOrUpdate(), which makes me wonder if it is calling save() when it should be calling update(). Is there any way to look at the objects that Hibernate has in the current Session for debugging purposes?

2

There are 2 answers

2
JB Nizet On BEST ANSWER

saveOrUpdate calls update if the detached entity already has an ID. update then tries to attach the given detached entity to the session. Since you can only have one instance of a given entity in the session, if you already have loaded the entity (using a load, a get or a query) in the session at the time saveOrUpdate is called, you'll get this exception.

saveOrUpdate should generally be one of the first things to do after opening a session. If you have to load the entity before updating it, you should use merge. I generally prefer using merge in all cases, because it's less error-prone.

You can have an idea of what's in the session using session.getStatistics().getEntityKeys().

1
Sebastian On

You may also want to set a breakpoint in the Session.Flush function and check which objects are stored in the persister. Here you may find some information how to track session-open and session-close events - you probably need to carefully examine the PersistenceContext property of the SessionImpl object and the OnFlush event.

To debug with the source code, you don't need to recompile all NHibernate sources - you may bind pdb files with the zip source file (have a look at http://lowleveldesign.wordpress.com/2011/10/02/debugging-nhibernate-prepare-symbol-files/).