Oui, c'est possible. C'est un cas particulier de la norme bidirectionnel ManyToOne/relation OneToMany. Il est spécial, parce que l'entité sur chaque extrémité de la relation est la même. Le cas général est détaillé dans la Section 2.10.2 de la JPA 2.0 spec.
Voici un exemple concret. Tout d'abord, la classe entity A
:
@Entity
public class A implements Serializable {
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
private Long id;
@ManyToOne
private A parent;
@OneToMany(mappedBy="parent")
private Collection<A> children;
// Getters, Setters, serialVersionUID, etc...
}
Voici une rude main()
méthode qui persiste de trois de trois entités:
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();
}
Dans ce cas, tous les trois instances d'entité doit être conservé avant validation de transaction. Si je ne persistent de l'une des entités dans le graphe de relations parent-enfant, alors une exception est levée sur commit()
. Sur Eclipselink, c'est un RollbackException
détaillant l'incohérence.
Ce comportement est configurable par l' cascade
attribut A
s'OneToMany et ManyToOne annotations. Par exemple, si j'ai mis en cascade=CascadeType.ALL
sur les deux de ces annotations, je pouvais en toute sécurité persistent, l'une des entités et ignore les autres. Dire que j'ai persisté parent
de mes transactions. L'implémentation JPA traverse parent
s' children
propriété, parce qu'il est marqué d' CascadeType.ALL
. L'implémentation JPA trouve son
et daughter
. Ensuite, il persiste deux enfants en mon nom, même si je n'ai pas de demande explicite.
Une remarque plus. C'est toujours le programmeur a la responsabilité de mettre à jour les deux côtés d'une relation bidirectionnelle. En d'autres termes, chaque fois que j'ai ajouter un enfant à un parent, je dois mettre à jour le parent de l'enfant de la propriété en conséquence. La mise à jour d'un seul côté d'une relation bidirectionnelle est une erreur en vertu de la JPA. Toujours mettre à jour des deux côtés de la relation. C'est écrit sans ambiguïté à la page 42 de la JPA 2.0 spec:
Notez que c'est la demande qui porte la responsabilité du maintien de la cohérence de l'exécution des relations-par exemple, pour s'assurer que le "un" et "plusieurs" côtés du une relation bidirectionnelle sont compatibles les uns avec les autres lors de l'application des mises à jour de la
la relation au moment de l'exécution.