【问题标题】:@PreRemove not being fired on child entity on CASCADE parent deletion@PreRemove 不会在 CASCADE 父删除时对子实体触发
【发布时间】:2020-04-29 02:29:09
【问题描述】:

我目前正在做一个 Springboot 项目,我遇到了一个问题:
我想在每个 Child 被删除之前触发一个方法,我的代码如下。

我有一个 Parent 类和一个 Child 一个遵循以下配置:

@Entity
public class Parent implements Serializable {

    private static final long serialVersionUID = 1L;

    @Id @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @OneToMany(mappedBy = "parent")
    @OnDelete(action = OnDeleteAction.CASCADE)
    private List<Child> children = new ArrayList<>();
}
@Entity
public class Child implements Serializable {

    private static final long serialVersionUID = 1L;

    @Id @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @ManyToOne
    @JoinColumn(name = "child_id", nullable = false)
    @Getter(onMethod = @__({@JsonIgnore}))
    private Parent parent;

    @PreRemove
    void test() {
        System.out.println("Before removing");
    }
}

我想要什么:Parent 对象被删除时,Anottation @OnDelete(action = OnDeleteAction.CASCADE) 将被触发,并且每个相关的 Child 对象也将被删除,但我想在它发生之前做一些逻辑。

发生了什么: 当一个 Parent 对象被删除时,Anottation @OnDelete(action = OnDeleteAction.CASCADE) 被触发并且所有相关的 Child 对象都被删除,但是带有@PreRemove 的方法不会被触发。

我需要添加更多配置吗?

【问题讨论】:

    标签: hibernate spring-boot jpa spring-data-jpa spring-data


    【解决方案1】:

    映射似乎有问题。您需要创建一个单独的事件侦听器类并在子实体上提及事件侦听器类名称(您也可以在实体本身中创建一个静态类)。 同样在父实体中,您需要选择 cascade.ALL

    @Entity
    @Table(name="PARENT")
    public class Parent {
    
        @Id
        @GeneratedValue(strategy = GenerationType.AUTO)
        private int id;
    
        @Column(name="NAME")
        private String name;
    
        @OneToMany(mappedBy = "parent",cascade = CascadeType.ALL)
        @OnDelete(action = OnDeleteAction.CASCADE)
        List<Child> childList=new ArrayList<>();
    
    
        public int getId() {
            return id;
        }
    
        public void setId(int id) {
            this.id = id;
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public void addChild(Child child)
        {
            child.setParent(this);
            childList.add(child);
        }
    }
    

    在类级别具有事件侦听器注释的子实体

    @Entity
    @Table(name="CHILD")
    @EntityListeners(ChildEntityListener.class)
    public class Child {
    
        @Id
        @GeneratedValue(strategy = GenerationType.AUTO)
        private int id;
    
        @Column(name="NAME")
        private String name;
    
        @ManyToOne
        @JoinColumn(name="PARENT_ID")
        Parent parent;
    
        public int getId() {
            return id;
        }
    
        public void setId(int id) {
            this.id = id;
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public Parent getParent() {
            return parent;
        }
    
        public void setParent(Parent parent) {
            this.parent = parent;
        }
    
    }
    

    事件监听类

    public class ChildEntityListener {
    
        @PreRemove
        void test(Child child) {
            System.out.println("Before removing Child Entity");
        }
    }
    

    它的调用代码

    public void entityListener() {
        Parent parent = new Parent();
        parent.setName("Test Parent");
    
        Child child = new Child();
        child.setName("Test Child");
        parent.addChild(child);
    
        Child child1 = new Child();
        child1.setName("Test Child 2");
        parent.addChild(child1);
    
        parentRepo.save(parent);
    
    
        List<Parent> parentList = parentRepo.findAll();
        for (Parent p : parentList) {
            parentRepo.delete(p);
    
        }
    
    }
    

    更多信息可以在这里找到enter link description here

    注意:- 如评论中所述,创建和添加 EventListener 类并将注释放在子实体上是可选的。

    【讨论】:

    • 谢谢!只需添加cascade = CascadeType.ALL 即可触发@PreRemove!没有必要创建 EventListener,但我猜它对更复杂的东西很有用。再次感谢!
    猜你喜欢
    • 1970-01-01
    • 2021-12-02
    • 1970-01-01
    • 1970-01-01
    • 2021-12-20
    • 1970-01-01
    • 2014-06-25
    • 1970-01-01
    • 2021-04-04
    相关资源
    最近更新 更多