Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>Yes, this is possible. This is a special case of the standard bidirectional <code>@ManyToOne</code>/<code>@OneToMany</code> relationship. It is special because the entity on each end of the relationship is the same. The general case is detailed in Section 2.10.2 of the <a href="http://jcp.org/aboutJava/communityprocess/final/jsr317/index.html" rel="noreferrer">JPA 2.0 spec</a>.</p> <p>Here's a worked example. First, the entity class <code>A</code>:</p> <pre><code>@Entity public class A implements Serializable { @Id @GeneratedValue(strategy=GenerationType.AUTO) private Long id; @ManyToOne private A parent; @OneToMany(mappedBy="parent") private Collection&lt;A&gt; children; // Getters, Setters, serialVersionUID, etc... } </code></pre> <p>Here's a rough <code>main()</code> method that persists three such entities:</p> <pre><code>public static void main(String[] args) { EntityManager em = ... // from EntityManagerFactory, injection, etc. em.getTransaction().begin(); A parent = new A(); A son = new A(); A daughter = new A(); son.setParent(parent); daughter.setParent(parent); parent.setChildren(Arrays.asList(son, daughter)); em.persist(parent); em.persist(son); em.persist(daughter); em.getTransaction().commit(); } </code></pre> <p>In this case, all three entity instances must be persisted before transaction commit. If I fail to persist one of the entities in the graph of parent-child relationships, then an exception is thrown on <code>commit()</code>. On Eclipselink, this is a <code>RollbackException</code> detailing the inconsistency.</p> <p>This behavior is configurable through the <code>cascade</code> attribute on <code>A</code>'s <code>@OneToMany</code> and <code>@ManyToOne</code> annotations. For instance, if I set <code>cascade=CascadeType.ALL</code> on both of those annotations, I could safely persist one of the entities and ignore the others. Say I persisted <code>parent</code> in my transaction. The JPA implementation traverses <code>parent</code>'s <code>children</code> property because it is marked with <code>CascadeType.ALL</code>. The JPA implementation finds <code>son</code> and <code>daughter</code> there. It then persists both children on my behalf, even though I didn't explicitly request it.</p> <p>One more note. It is always the programmer's responsibility to update both sides of a bidirectional relationship. In other words, whenever I add a child to some parent, I must update the child's parent property accordingly. Updating only one side of a bidirectional relationship is an error under JPA. Always update both sides of the relationship. This is written unambiguously on page 42 of the JPA 2.0 spec:</p> <blockquote> <p>Note that it is the application that bears responsibility for maintaining the consistency of runtime relationships—for example, for insuring that the “one” and the “many” sides of a bidirectional relationship are consistent with one another when the application updates the relationship at runtime.</p> </blockquote>
 

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