I am using the Hibernate 4.3.6 and I made use of the latest Maven bytecode enhancement to instrument all entities for self dirtiness awareness.
I added the maven plugin:
<build> <plugins> <plugin> <groupId>org.hibernate.orm.tooling</groupId> <artifactId>hibernate-enhance-maven-plugin</artifactId> <executions> <execution> <phase>process-test-resources</phase> <goals> <goal>enhance</goal> </goals> </execution> </executions> </plugin> </plugins> </build>
and I see my entities are being enhanced:
@Entity public class EnhancedOrderLine implements ManagedEntity, PersistentAttributeInterceptable, SelfDirtinessTracker { @Id @GeneratedValue(strategy=GenerationType.AUTO) private Long id; private Long number; private String orderedBy; private Date orderedOn; @Transient private transient PersistentAttributeInterceptor $$_hibernate_attributeInterceptor; @Transient private transient Set $$_hibernate_tracker; @Transient private transient CollectionTracker $$_hibernate_collectionTracker; @Transient private transient EntityEntry $$_hibernate_entityEntryHolder; @Transient private transient ManagedEntity $$_hibernate_previousManagedEntity; @Transient private transient ManagedEntity $$_hibernate_nextManagedEntity; ...
While debugging, I am checking org.hibernate.event.internal.DefaultFlushEntityEventListener#dirtyCheck
method:
if ( entity instanceof SelfDirtinessTracker ) { if ( ( (SelfDirtinessTracker) entity ).$$_hibernate_hasDirtyAttributes() ) { dirtyProperties = persister.resolveAttributeIndexes( ( (SelfDirtinessTracker) entity ).$$_hibernate_getDirtyAttributes() ); } }
and the $$_hibernate_hasDirtyAttributes()
always returns false.
This is because $$_hibernate_attributeInterceptor
is always null, so when setting any property:
private void $$_hibernate_write_number(Long paramLong) { if (($$_hibernate_getInterceptor() == null) || ((this.number == null) || (this.number.equals(paramLong)))) break label39; $$_hibernate_trackChange("number"); label39: Long localLong = paramLong; if ($$_hibernate_getInterceptor() != null) localLong = (Long)$$_hibernate_getInterceptor().writeObject(this, "number", this.number, paramLong); this.number = localLong; }
because the $$_hibernate_getInterceptor()
is null the trackChange will be bypassed, hence the bytecode enhancement will not resolve the dirty properties and the default deep-comparison algorithm will be used.
What am I missing? How can I get the $$_hibernate_attributeInterceptor
to be properly set so that the dirty properties are tracked by the bytecode instrumentation methods?
Hibernate 5 fixes this issue and now the dirty checking for a setter looks like this:
public void $$_hibernate_write_title(String paramString) { if (!EqualsHelper.areEqual(this.title, paramString)) { $$_hibernate_trackChange("title"); } this.title = paramString; } public void $$_hibernate_trackChange(String paramString) { if (this.$$_hibernate_tracker == null) { this.$$_hibernate_tracker = new SimpleFieldTracker(); } this.$$_hibernate_tracker.add(paramString); }
So, the solution is an upgrade to Hibernate 5.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With