I have an object graph as follows
Code:
Product
|
|----(many-to-one)----Address
| |
| |----(one-to-many)----AddressKeys (Set)
|
|----Name
When I call merge() passing in an
already persisted product, with the product name different to the persistend name I expect only the version of the product object to be updated, and as a result only an update statement made to the product table in the database.
However, in reality the Address and AddressKeys get their version incremented as well and an update sql expression is therefore executed on their database tables.
I have debugged the hibernate code (3.2.0CR2), and also the head of CVS at the time of writing this. It appears that Hibernate thinks the AddressKeys collection is dirty and requires updating.
I think I have tracked down the culprit code inside org.hibernate.type.CollectionType at abount line 449 in the replace method, but as I'm no expert with the Hibernate code can someone confirm this is the cause.
Code:
public Object replace(
final Object original,
final Object target,
final SessionImplementor session,
final Object owner,
final Map copyCache)
throws HibernateException {
.....
if (original==target) {
//get the elements back into the target
//TODO: this is a little inefficient, don't need to do a whole
// deep replaceElements() call
replaceElements( result, target, owner, copyCache, session );
result = target;
}
....
}
It looks as though whether or not the collection has changed the elements are replaced and hence it is marked as dirtyand the versions are incremented.
Can someone please confirm whether this is correct and an inefficiency that is present at the moment.
Thank you
Adrian