Note that there are some explanatory texts on larger screens.

plurals
  1. PO(new title) jpa merge not working well with bidirectional java relations
    primarykey
    data
    text
    <p><strong>Problem was partially solved, raising new, more specific question. I suggest skipping the old content.</strong></p> <p><em>Previous title: "Cascade merge overlapping object trees in jpa":</em></p> <blockquote> <p><em>I have multiple trees of jpa entities. The relation parent&lt;->child is bidirectional in java. Both parent and child have reference to each other. The relation on database side is always from child to parent, no jointables. The trees overlap each other. There are cycles (in the sum of trees). I want to merge all objects calling EntityManager.merge() on trees' roots. I tried setting CascadeType.ALL on all relations on parents' sides. The result is always as follows, no matter what is the order of roots to merge: java.lang.IllegalStateException: org.hibernate.TransientPropertyValueException: Not-null property references a transient value - transient instance must be saved before current operation: com.example.Foo1 -> com.example.Foo2</em></p> <p><em>What should I do to make it right?</em></p> </blockquote> <p><strong>New question (UPDATE):</strong></p> <p>The cause is indeed bidirectional java relation not being cascaded well if using merge (works well for persist). Thus I want to ask a new, more specific question based on the following scenario:</p> <p>Class A:</p> <pre><code> @Entity class A { @OneToMany(mappedBy = "a", cascade = CascadeType.All) List&lt;B&gt; bs; //... } </code></pre> <p>Class B:</p> <pre><code> @Entity class B { @ManyToOne A a; //... } </code></pre> <p>execution:</p> <pre><code> A a = new A(); B b = new B(); a.setBs(Arrays.asList(new B[]{b}); b.setA(a); //em.persist(a) works as desired. //Probably because inserts are postponed to the end of transaction. em.merge(a); //throws exception: </code></pre> <p><em>java.lang.IllegalStateException: org.hibernate.TransientPropertyValueException: Not-null property references a transient value - transient instance must be saved before current operation: com.example.B -> com.example.A</em></p> <p>If I understand correctly, <code>a</code> being merged, and having cascade on, tries to execute merge on his child <code>b</code>, before his own merge. But the correct order of database operation is first insert <code>a</code> then insert <code>b</code>. </p> <p>I solved the problem resigning from the cascade. But can we make cascade work here? Seems physically possible for me.</p>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload