dcernahoschi
dcernahoschi

Reputation: 15250

Transitive persistence order in hibernate

I have 2 parent classes A, C and 2 children: B, D. Both relationships have transitive persistence enabled. However persisting D requires B to be persistent.

class A {
    @OneToMany(cascade = {CascadeType.PERSIST}, mappedBy = "a")
    public Set<B> getBs() {
     ...
    }
}

class B {
    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "a_id", nullable = false)
    public A getA() {
      ...
    }
}

class C {
    @OneToMany(cascade = {CascadeType.PERSIST}, mappedBy = "c")
    public Set<D> getDs() {
       ...
    }
}

class D {
    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "b_id", nullable = false)
    public B getB() {
      ...
    }

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "c_id", nullable = false)
    public C getC() {
      ...
    }
}

What I am trying is to save both B and D in one shot:

A a = entityManager.getReference(...);
C c = entityManager.getReference(...);

B b = new B();

D d = new D();
d.setB(b);

a.add(b);
b.setA(a);

c.add(d);
d.setC(c);

entityManager.flush();

I assume this should be possible. However I get a TransientObjectException telling that B needs to be persistent when trying to save D.

Is there a specific order the cascading relations are processed by hibernate?

Upvotes: 1

Views: 1249

Answers (1)

JB Nizet
JB Nizet

Reputation: 692181

When you flush, d is made persistent thanks to the cascade from C to D. But there is no cascade from D to B, so Hibernate complains. A would need to be flushed before D for it to work, but there's no reason to have any specific order between A and D.

Upvotes: 2

Related Questions