Да, это возможно. Это особый случай стандартных двунаправленных отношений @ManyToOne
/ @OneToMany
. Это особенное, потому что сущность на каждом конце отношений одинакова. Общий случай подробно описан в разделе 2.10.2 спецификации JPA 2.0 .
Вот рабочий пример. Во-первых, класс сущности 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...
}
Вот грубый main()
метод, который сохраняет три таких объекта:
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();
}
В этом случае все три экземпляра сущности должны быть сохранены до принятия транзакции. Если мне не удается сохранить одну из сущностей в графе родительско-дочерних отношений, то возникает исключение commit()
. На Eclipselink это RollbackException
, детализирующее несоответствие.
Это поведение настраивается с помощью атрибута cascade
в аннотациях A
* @OneToMany
и @ManyToOne
. Например, если я установлю cascade=CascadeType.ALL
в обеих этих аннотациях, я смогу безопасно сохранить одну из сущностей и игнорировать другие. Скажем, я сохранил parent
в моей транзакции. Реализация JPA пересекает свойство parent
children
, поскольку оно помечено CascadeType.ALL
. Реализация JPA находит там son
и daughter
. Затем он сохраняет обоих детей от моего имени, хотя я не просил об этом явно.
Еще одна заметка. Программист всегда обязан обновлять обе стороны двунаправленных отношений. Другими словами, всякий раз, когда я добавляю дочерний элемент к некоторому родителю, я должен соответствующим образом обновлять родительское свойство дочернего элемента. Обновление только одной стороны двунаправленной связи является ошибкой в соответствии с JPA. Всегда обновляйте обе стороны отношений. Это написано однозначно на странице 42 спецификации JPA 2.0:
Обратите внимание, что именно приложение несет ответственность за поддержание согласованности отношений времени выполнения - например, за обеспечение того, чтобы стороны «одна» и «многие» двунаправленных отношений соответствовали друг другу, когда приложение обновляет
отношения во время выполнения.