Update of not-null foreign key column to null if relation is owned on "parent" side
Description
Activity

Andreas Benneke April 1, 2016 at 10:16 PM
Great, thank you for clarifying this! We never realized that we got two associations without the mappedBy
.

Former user April 1, 2016 at 9:43 PM
You need to have @OneToMany(..., mappedBy = "parent")
, otherwise you will have 2 associations that are not bidirectional that use the same foreign key, which is not supported.
JPA 2.1, Section 3.4.2 Version Attributes says:
"All non-relationship fields and properties and all relationships owned by the entity are included in version checks"
Section 2.10.2, Bidirectional ManyToOne / OneToMany Relationships says:
"Assuming that:
Entity A references a single instance of Entity B.
Entity B references a collection of Entity A [21]
.
Entity A must be the owner of the relationship."
If you want to include the collection in optimistic locking checks, then @OptimisticLock(excluded = false)
is the way to go.

Andreas Benneke October 28, 2015 at 11:19 AM
Verified that the problem still exists in 4.3.11 und 5.0.2.

Andreas Benneke July 18, 2015 at 11:09 PM
The mapping is getting out of control if you just repeat the mandatory case at the @JoinColumn
:
In this case, Hibernate seems to lose the connection between the relations and tries to generate the parent_id
column twice:
But this seems to be a different story?
Exploring the possibilities on optimistic locking while tracking changes on a
OneToMany
-relation we tried to setup the relation in a way where the parent is "owner". This does not seem to be very common nor well documented, so we may be led astray here - it however seems to be supported to some extend:The easy case is that the relation is unidirectional from parent to child
with no corresponding relation on the child side the parent is clearly the owner. The parent version is perfectly updated in this case when children are added or removed.
A more complex case is when we add the relation on the child side making it bidirectional - the "optional" case first:
Please note, that there is (still) no
mappedBy
at theOneToMany
annotation. If there would be, the child would be the owner of the relation and we would lose the optimistic locking on collection changes.This bidirectional-optional scenario works as expected as well. However while removing a child Hibernate issues an extra update on that child to set the parent to
null
right before deleting it:If you now make the child-to-parent-relation mandatory
removing a child is no longer possible due to the extra update mentioned above which leads to a "NULL not allowed" exception.
To complete the cycle we finally found a way to handle the mandatory case as well using (abusing?) the
@OptimisticLock
annotation:on the parent side and
at the child side. This bidirectional-mandatory-optimistic-lock scenario works as expected now.
You may find all cases in a test project on Github https://github.com/abenneke/sandbox/tree/master/hibernate-versions as
*ParentOwnedTest
.Thank you!