Originally posted by Mike Weiss: 1. How does Hibernate detect changes in Object graphs (diffs) to generate appropriate SQL-Statements. E.g. if OrderItem instance is removed from Order list container ?
My understanding of the mechanisms Hibernate uses are based on building my own frameworks over the years and in porting an EJB (session and entity beans) application to Hibernate over the past month. Caveat emptor.
When you load objects via the Session interface, Hibernate clones them and gives you a copy. It stores both the originals and copies in the Session's cache, known as a unit of work. When you tell the Session to flush, it compares the copies to the originals to determine what SQL to issue.
This is decidely different from another, though more intrusive, option: have the objects track their own changes. This latter method is very useful when you cannot keep the session open during the course of the transaction, as in a rich client or distributed architecture.
Hibernate provides methods for working around this. In the simplest case, you can reassociate object graphs with a new Session instance with saveOrUpdateCopy(). Hibernate will reload fresh copies of the objects and put them and your versions into the Session cache for comparison during the next flush().
2. Is it possible to use only the cache implementation classes in order to create an object cache for e.g. Rich Client purposes ?
As Karl said, Hibernate provides a cache interface for others to implement (though it provides several implementations). Hibernate places this cache between the Session and the database. The Session becomes the "first-level" cache and the trans-Session one is called the "second-level" cache. If you request object A with ID X, it checks the Session, then the second-level cache, and finally the database. [ December 20, 2004: Message edited by: David Harkness ]
Originally posted by Mike Weiss: I need to clearify my question: What is the algorithm to detect changes in object graphs if the object (itself) doesn't track it's changes (e.g. enrich all setXX, addXX, removeXX methods).
Well, now I'm simply making an educated guess, but here goes. You can tell Hibernate to access your properties using accessor methods or direct field access (reflection). Similarly, for associations you use the standard Java Collections framework. Thus, Hibernate has all it needs to do object diffs. It doesn't need to enhance your classes at all.*
If you look at the class Karl mentioned, Interceptor, you can see it calls a method to detect a dirty object that takes the object itself and two arrays of its properties (original and new values). I suspect the standard implementation merely compares the arrays using equals() on each element with other various trickery to avoid NPE and such.
Associations are a little more difficult. I assume Hibernate uses a simple algorithm for diffing each Collection type. This is where tracking changes could pay off considerably if you associations get large.
Do you have an example how to use the Hibernate cache implementation ?
I haven't set this up in our ported application yet, but we'll be using Tangosol's Coherence distributed cache, no doubt. There is some basic documentation on hibernate.org; have you checked it out yet?
* Hibernate does use its own lazy-loading Collections when loading your associations. While they cuold track changse, I think I read that it doesn't. Its Collections are strictly for supporting lazy loading. Don't quote me on that one, though.
yeah, but ... what would PIE do? Especially concerning this tiny ad: