Unidirectional one-to-many doesn't take care of many side during removal if bytecode enhancement is on

Description

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.

Attachments

1

Activity

Show:

Former user March 15, 2017 at 12:21 AM

Fixed in 5.1 branch as well.

Luis Barreiro January 28, 2017 at 3:35 PM
Edited

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.

Fixed

Details

Assignee

Reporter

Components

Fix versions

Affects versions

Priority

Created July 25, 2016 at 10:41 AM
Updated May 19, 2017 at 5:39 AM
Resolved March 15, 2017 at 12:21 AM