JPA:单向多对一和级联删除

per*_*erp 87 java jpa many-to-one jpa-2.0

假设我有如下的单向 @ManyToOne关系:

@Entity
public class Parent implements Serializable {

    @Id
    @GeneratedValue
    private long id;
}

@Entity
public class Child implements Serializable {

    @Id
    @GeneratedValue
    private long id;

    @ManyToOne
    @JoinColumn
    private Parent parent;  
}
Run Code Online (Sandbox Code Playgroud)

如果我有一个父P和子C 1 ... C n引用回P,那么在JPA中有一个干净漂亮的方法可以在删除P时自动删除子C 1 ... C n(即entityManager.remove(P))?

我正在寻找的是类似于ON DELETE CASCADESQL 的功能.

Tho*_*ker 80

如果您使用hibernate作为JPA提供程序,则可以使用注释@OnDelete.此注释将添加触发器ON DELETE CASCADE的关系,它将子项的删除委托给数据库.

例:

public class Parent {

        @Id
        private long id;

}


public class Child {

        @Id
        private long id;

        @ManyToOne
        @OnDelete(action = OnDeleteAction.CASCADE)
        private Parent parent;
}
Run Code Online (Sandbox Code Playgroud)

使用此解决方案,从孩子到父母的单向关系足以自动删除所有孩子.此解决方案不需要任何侦听器等.此外,DELETE FROM Parent WHERE id = 1之类的查询将删除子节点.

  • 谢谢你的回答.快速注意:只有在通过休眠启用DDL生成时才会创建数据库级联触发器.否则你将不得不以另一种方式添加它(例如liquibase)以允许直接针对数据库运行的即席查询,如'DELETE FROM Parent WHERE id = 1'执行级联删除. (8认同)
  • 我不能让它以这种方式工作,是否有任何特定版本的hibernate或其他更详细的例子? (4认同)
  • 很难说为什么它对您不起作用。要使此工作正常进行,您可能需要重新生成架构,或者必须手动添加级联删除。@OnDelete批注似乎已经存在了一段时间,因此我不认为该版本是个问题。 (2认同)

Vin*_*lds 69

JPA中的关系始终是单向的,除非您在两个方向上将父级与子级关联.从父母到孩子的级联REMOVE操作将需要从父母到孩子的关系(而不仅仅是相反的).

因此,您需要这样做:

  • 或者,将单向@ManyToOne关系更改为双向关系@ManyToOne或单向关系@OneToMany.然后,您可以级联REMOVE操作,以便EntityManager.remove删除父项和子项.您还可以指定orphanRemoval为true,以便在父集合中的子实体设置为null时删除任何孤立子项,即在子项不存在于任何父项集合中时将其删除.
  • 或者,将子表中的外键约束指定为ON DELETE CASCADE.您需要在调用EntityManager.clear()之后调用,EntityManager.remove(parent)因为需要刷新持久性上下文 - 在数据库中删除子实体后,子实体不应该存在于持久性上下文中.

  • 有没有办法用JPA注释做No2? (6认同)
  • 如何使用Hibernate xml映射执行No2? (2认同)

tek*_*ara 13

创建一个双向关系,如下所示:

@Entity
public class Parent implements Serializable {

    @Id
    @GeneratedValue
    private long id;

    @OneToMany(mappedBy = "parent", cascade = CascadeType.REMOVE)
    private Set<Child> children;
}
Run Code Online (Sandbox Code Playgroud)

  • 糟糕的答案,JPA中的双向关系很糟糕,因为在大型儿童套装上进行操作需要花费大量时间 (7认同)
  • 有证据表明双向关系很慢吗? (2认同)
  • @Enerccio 我认为每个人都在连接上使用延迟加载。那么为什么它仍然是一个性能问题呢? (2认同)

归档时间:

查看次数:

85424 次

最近记录:

5 年,12 月 前