Hi,
Seems like Hibernate does not properly handle empty Embedded (embedded with all properties set to null). Every time we read from the database the object with null Embedded, it gets marked as dirty because our Entity creates instance of the Embedded but not making any assignments to its properties. That translates into database update after each read.
That’s what the doc says on component mapping (embedded)
http://www.hibernate.org/hib_docs/v3/re ... components
Quote:
The null value semantics of a component are ad hoc. When reloading the containing object, Hibernate will assume that if all component columns are null, then the entire component is null. This should be okay for most purposes.
Which means that embedded objects with no assigned properties will be rehydrated as null on next fetch, which is logical as there is nothing in the database that indicates that object was ever assigned.
But here’s the code from ComponentType (hibernate mapping for embedded). Before flush session traverses through all columns and checks if they were changed by calling isEqual with old and new value.
If any of the object, old or new, is null, it automatically assumes unequalness and marks it as dirty, when in fact it should have also checked all contained properties and if all of them are null, treat the Embedded as null too, as semantically Embedded with all null properties IS equivalent to null.
Code:
public boolean isEqual(Object x, Object y, EntityMode entityMode)
throws HibernateException {
if ( x == y ) {
return true;
}
if ( x == null || y == null ) {
return false;
}
Object[] xvalues = getPropertyValues( x, entityMode );
Object[] yvalues = getPropertyValues( y, entityMode );
for ( int i = 0; i < propertySpan; i++ ) {
if ( !propertyTypes[i].isEqual( xvalues[i], yvalues[i], entityMode ) ) {
return false;
}
}
return true;
}