是的,这是可能的。这是标准双向@ ManyToOne / @ OneToMany关系的特殊情况。它是特别的,因为在每一端的实体关系是相同的。一般情况详见
JPA 2.0 spec的2.10.2节。
这里有一个工作示例。首先,实体类A:
@Entity
public class A implements Serializable {
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
private Long id;
@ManyToOne
private A parent;
@OneToMany(mappedBy="parent")
private Collection 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。
此行为可以通过A的@OneToMany和@ManyToOne注释的cascade属性进行配置。例如,如果我在这两个注释上设置cascade = CascadeType.ALL,我可以安全地保留一个实体,忽略其他实体。说我坚持父在我的事务。 JPA实现遍历父级的children属性,因为它被标记为CascadeType.ALL。 JPA实现找到了儿子和女儿。它然后坚持两个孩子为我代表,即使我没有明确要求。
还有一个注意。程序员始终负责更新双向关系的双方。换句话说,每当我向一个父代添加一个子代时,我必须相应地更新子代的父属性。仅更新双向关系的一侧是JPA下的错误。始终更新关系的两侧。这是清楚地写在JPA 2.0规范的第42页:
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.