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

2022-08-31 09:13:17

假设我有一个单向关系,如下所示:@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;  
}

如果我有父母P和孩子C1...Cn引用回P,在JPA中是否有一种干净漂亮的方法来自动删除子级C1...Cn 当 P 被移除时(即 )?entityManager.remove(P)

我正在寻找的是类似于SQL中的功能。ON DELETE CASCADE


答案 1

如果使用休眠作为 JPA 提供程序,则可以使用注释 。此注释将添加到触发器的关系中,触发器将子项的删除委托给数据库。@OnDeleteON DELETE CASCADE

例:

public class Parent {
   
        @Id
        private long id;

}


public class Child {
        
        @Id
        private long id;
  
        @ManyToOne
        @OnDelete(action = OnDeleteAction.CASCADE)
        private Parent parent;
}
     

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


答案 2

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

因此,您需要执行以下操作:

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

推荐