有一个实体类“A”。 A 类可能有相同类型“A”的子级。如果它是 child ,“A”也应该持有它的 parent 。
这可能吗?如果是这样,我应该如何映射实体类中的关系? [“A”有一个 id 列。]
最佳答案
是的,这是可能的。这是标准双向 @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<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
,详细说明了不一致。
此行为可通过 A
的 @OneToMany
和 @ManyToOne
注释上的 cascade
属性进行配置。例如,如果我在这两个注释上设置 cascade=CascadeType.ALL
,我可以安全地保留其中一个实体并忽略其他实体。假设我在交易中坚持 parent
。 JPA 实现遍历 parent
的 children
属性,因为它被标记为 CascadeType.ALL
。 JPA 实现在那里找到 son
和 daughter
。然后它代表我保留两个 child ,即使我没有明确要求它。
还有一个注意事项。更新双向关系的双方始终是程序员的责任。换句话说,每当我将 child 添加到某个父级时,我都必须相应地更新 child 的父级属性。仅更新双向关系的一侧是 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.
关于java - JPA:如何具有相同实体类型的一对多关系,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3393515/