Unidirectional one-to-many doesn't take care of many side during removal if bytecode enhancement is on
Description
Attachments
causes
is duplicated by
Activity

Former user March 15, 2017 at 12:21 AM
Fixed in 5.1 branch as well.

Luis Barreiro January 28, 2017 at 3:35 PMEdited
A brief description on the mechanics of this issue and the solution for it.
The 'nulling' of foreign keys is called a cascading action, in particular the CollectionRemoveAction
was not being called in this case. CollectionRemoveAction
are created on AbstractFlushingEventListener
where it iterates over a list CollectionEntry
in the PersistenceContext
. For collections not initialized yet there was no CollectionEntry
and therefore their keys were not being 'nulled'.
CollectionEntry
are added as part of the load process, and in particular in the type resolution of CollectionType
. For lazy fields, type resolution is always skipped on load because the value that results from that process is not needed. Resolution can occur on later if there is a lazy loading. This clearly has to change, so that type resolution is always done for collections.
There is still one difference between resolving a lazy and a eager collection. In the lazy case, the PersistentCollection
must not be added to the 'hydratedState' of the entity or else the collection will be loaded when the attribute values are set on the entity object.
In an unidirectional one-to-many relation, with a join column on many side, Hibernate seems to forget about nulling foreign keys when removing object on 'one' side if entities are instrumented.
In my test-case (please see it attached) there is Garage entity keeping a set of Cars entities. During removal (without bytecode enhancement) of Garage entity, Hibernate issues the following statements:
However when entities are instrumented using 'enableLazyInitialization' mode, the first SQL statement is not generated which leads to constraint violation when the delete statement is executed.
In order to run my test-case with bytecode enhancement (which fails), please issue the following command:
A build run without 'enhancement' profile works correctly.
Please note that this happens only when 'enableLazyInitialization' mode is on; other modes doesn't cause this issue.