Collection deleted due to orphan removal fails with constraint violation

Description

See the original project in the attachment.
I have an entity B, which owns an entity A in a 1-to-1 relationship. A may exist without B, but not vice-versa. Besides, multiple instances of C may be associated with B, though instances of C may also exist without being related to B. I have marked B with CascadeType.All and enabled orphan removal in A, C is marked with CascadeType.All end orphan removal enabled on B as follows:

class A {
ID id;

@OneToOne ( mappedBy = "A", orphanRemoval=true, cascade = CascadeType.ALL)
B b; }

class B {
ID id;

@NotNull
@OneToOne (optional = false)
@JoinColumn(name = "a_id", nullable = false, referencedColumnName = "id" updatable = true, unique = true)
A a;

@OneToMany ( fetch = FetchType.EAGER, cascade = CascadeType.ALL, orphanRemoval = true)
@JoinTable(name="B_to_C", joinColumns = @JoinColumn(name="B_id", referencedColumnName = "id"), inverseJoinColumns = @JoinColumn(name="C_id", referencedColumnName="id"))
Set<C> listOfCs;}

Following will now fail:

A a = new A();
B b = new B();
b.setCList(getABunchOfTransientCsByMagic());
a.setB(b);
b.setA(a);
a = aRepository.save(A);
a.setB(null);
aRepository.save(a);

The last statement will fail for hurting the fk constraint lying on b_id in the b_to_c join table. The reason for this is, that Hibernate is putting the delete actions (deletion of B, B_to_C and C) in the wrong order. Debugging showed, that in the session's action queue B is deleted first, then the entries in B_to_C and finally the C instances. The funny thing about this is, that if A is owning B, everything just works fine (B_to_C table is deleted before B is accessed).

Attachments

3
  • 28 Mar 2014, 01:05 PM
  • 28 Mar 2014, 12:59 PM
  • 28 Mar 2014, 12:20 PM

Activity

Former userJanuary 29, 2015 at 2:57 AM

Fixed in master, 4.3, and 4.2 branches.

Former userDecember 3, 2014 at 6:29 AM

I've pushed a FailureExpected test case to master, 4.3, and 4.2 branches: org.hibernate.test.orphan.one2one.fk.bidirectional.multilevelcascade.DeleteMultiLevelOrphansTest.

Former userNovember 20, 2014 at 7:19 PM

Caused by HHH-6484.

Martin PuffeMarch 28, 2014 at 1:27 PM

Please excuse my missing experience with Jira. Above code snippets again, now in a code block:

class A { ID id; @OneToOne ( mappedBy = "A", orphanRemoval=true, cascade = CascadeType.ALL) B b; }
class B { ID id; @NotNull @OneToOne (optional = false) @JoinColumn(name = "a_id", nullable = false, referencedColumnName = "id" updatable = true, unique = true) A a; @OneToMany ( fetch = FetchType.EAGER, cascade = CascadeType.ALL, orphanRemoval = true) JoinTable(name="B_to_C", joinColumns = @JoinColumn(name="B_id", referencedColumnName = "id"), inverseJoinColumns = @JoinColumn(name="C_id", referencedColumnName="id")) Set<C> listOfCs; }

Martin PuffeMarch 28, 2014 at 1:04 PM

This file relates to the project, if A holds the id of B, thus the working example of my test run. For the actual one, see Log2.txt

Fixed

Details

Assignee

Reporter

Components

Affects versions

Priority

Created March 28, 2014 at 12:20 PM
Updated January 29, 2015 at 3:07 AM
Resolved January 29, 2015 at 2:57 AM

Flag notifications