The fix for HHH-6848 causes IllegalStateException when merging an entity results in merging more than one representation of the same detached entity.
For example, Hibernate throws IllegalStateException when merging entity 'x' if it has references to 2 detached entities 'y1' and 'y2' (obtained from different sessions), and y1 and y2 represent the same persistent entity.
When one of Documentation will be added to the representations manual by HHH-9216. Here is some documentation to get people going.
OVERVIEW:
A new configuration property, hibernate.event.merge.entity_copy_observer, controls how Hibernate will respond when multiple representations of the same persistent entity ( " root entity copy " object being merged (e ) is detected while merging . g
hibernate . , session event .merge .entity_copy_observer can be set to one of the following values: * disallow ( y1 the default ) ), and another representation : throws IllegalStateException if an entity copy is encountered on cascade- detected; * allow: performs the merge , operation on each entity copy that is detected; * log: (provided for testing only) performs the merge result should operation on each entity copy that is detected and logs information about the entity copies. This setting requires DEBUG logging be as copied from enabled for org.hibernate.event.internal.EntityCopyAllowedLoggedObserver.
In addition the root object; application may customize the behavior by providing an implementation of org.hibernate.event.spi.EntityCopyObserver and setting hibernate.event.merge.entity_copy_observer to the representation encountered while cascading should be ignored class name .
When top-level merges are used to hibernate.event. merge multiple representations .entity_copy_observer=allow or log, Hibernate will merge each entity copy detected while cascading the merge operation. In the process of merging each entity copy, Hibernate will cascade the same merge operation from each entity as in:
{code} y copy to its assocations with cascade = (Y) s CascadeType . merge( y1 ); MERGE or CascadeType.ALL. The entity state resulting from merging an entity copy will be overwritten when another entity copy is merged. y = There are no known issues with merging multiple entity copies as long as they are consistent ( Y) s i . merge( y2 e. have the same property/association values ) ; . {code} RISKS OF MERGING ENTITY COPIES: The Because cascade order is undefined, the order in which the entity copies are merged is undefined. As a result, if property values in the entity copies are not consistent, the resulting entity state will be indeterminate and data will be lost from y2 should "win" all entity copies except for the last one merged .
In other cases If an entity copy cascades the merge operation to an association that is (or contains) a new entity , one representation that new entity will "win"; any other representations be merged (i.e, persisted and the merge operation will be ignored cascaded to its associations according to its mapping), even if that same association is ultimately overwritten when Hibernate merges a different representation having a different value for its association . Because cascade-order If the association is indeterminate mapped with orphanRemoval=true , it the new entity will not be possible to know which will be deleted because the winner semantics of orphanRemoval do not apply if the entity being orphaned is a new entity .
It There are known issues when representations of the same persistent entity have different values for a collection. See HHH-9239 and HHH-9240 for details. These issues can cause data loss or corruption.
By setting hibernate.event.merge.entity_copy_observer=allow or log, Hibernate will allow entity copies of any type of entity to be merged. The only way to exclude particular entity classes or associations that contain critical data is possible to log provide a custom implementation of org.hibernate.event.spi.EntityCopyObserver with the current database state desired behavior , and setting hibernate.event.merge.entity_copy_observer to the winner class name.
RECOMMENDATIONS:
Hibernate provides limited DEBUG logging capabilities that can help determine the entity classes for which entity copies were found. By setting hibernate.event.merge.entity_copy_observer=log and losers enabling DEBUG logging for org . hibernate.event.internal.EntityCopyAllowedLoggedObserver, the following will be logged each time an application calls EntityManager.merge( entity ) or Session.merge( entity ): - number of times multiple representations of the same persistent entity was detected summarized by entity name; We'll need to work out - details about what gets logged by entity name and ID, including output from calling toString() on each representation being merged as well as the merge result.
The log level (INFO should be reviewed to determine if multiple representations of entities containing critical data are detected. If so , WARN the application should be modified so there is only one representation , and a custom implementation of org . hibernate . event . ) spi.EntityCopyObserver should be provided to disallow entity copies for entities with critical data.
Using optimistic locking is recommended to detect if different representations are from different versions of the same persistent entity. If they are not from the same version, Hibernate will throw StaleObjectStateException.
|