views:

1090

answers:

3

An object I mapped with hibernate has strange behavior. In order to know why the object behaves strangely, I need to know what makes that object dirty. Can somebody help and give me a hint?

The object is a Java class in a Java/Spring context. So I would prefer an answer targetting the Java platform.

Edit: I would like to gain access to the Hibernate dirty state and how it changes on an object attached to a session. I don't know how a piece of code would help.

As for the actual problem: inside a transaction managed by a Spring TransactionManager I do some (read) queries on Objects and without doing an explicit save on these Objects they are saved by the TransactionManager because Hibernate thinks that some of these (and not all) are dirty. Now I need to know why Hibernate thinks those Objects are dirty.

A: 

Assuming that the state of the object cannot be accessed directly (e.g. no public or package protected fields) and is not fiddled with by reflection, you can put a breakpoint at the start of all of the object's methods and run through the scenario that makes the object dirty in the debugger.

Nat
A: 
  1. create a Test Case or similar, so you can reproduce the problem with a single click.
  2. enable logging for org.hibernate check the logging for the string "dirty" (actually you don't need all of org.hibernate, but I don't know the exact logger.
  3. Find to spots in the program, one where the entity is not dirty, one where it is dirty. Find the middle of the code between the two points, and put a logging statement there, for logging the isdirty Value. Continue with the strategy until you have reduced the code to a single line.
  4. Check out the hibernate code. Find the code that does the dirty checking. Use a debugger to step through it.
Jens Schauder
+2  A: 

I would use an interceptor. The onFlushDirty method gets the current and previous state so you can compare them. Implement the Interceptor interface and extend EmptyInterceptor, overriding onFlushDirty. Then add an instance of that class using configuration.setInterceptor (Spring may require you to do this differently). You can also add an interceptor to the session rather than at startup.

Here is the documentation on interceptors.

Brian Deterling
That won't tell you *what* made an object dirty only which fields are dirty. The flush happens after the object changes state, often at the end of the transaction.
Nat