java - JPA:如何具有相同实体类型的一对多关系

标签 java orm jpa hierarchy one-to-many

有一个实体类“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 实现遍历 parentchildren 属性,因为它被标记为 CascadeType.ALL。 JPA 实现在那里找到 sondaughter。然后它代表我保留两个 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/

相关文章:

java - 仅当查询未找到任何结果时才出现错误 java.lang.ClassNotFoundException : org. springframework.orm.jpa.EntityManagerFactoryUtils

java - 异常由于从互联网/本地引用 struts.dtd 文件

java - 在类中存储 byte[]

java - Spring JPA 和 Couchbase - com.couchbase.client.java.error.ViewDoesNotExistException : View cat/all does not exist

reflection - 使用 gorm 库进行反射(reflect)

orm - PetaPoco 是否处理枚举?

java - 在表之间链接@ManyToOne 时如何创建对象

java - 如何在不调用receive的情况下判断数据报包是否到达?

java - 在 Hibernate 中使用复合主键映射集合

Symfony2 Doctrine2 与可选的一对一关系存在问题