java - Hibernate中级联删除的问题

标签 java hibernate orm cascading-deletes

这个问题已经被问过很多次了,至今没有看到满意的答案,所以我再问一次。

想象以下情况:

public class User {
    ...

    @Cascade(value= {CascadeType.DELETE})
    @OneToMany(fetch = FetchType.LAZY)
    @JoinColumn(name="followerId")
    public List<LocationFollower> followedLocations;

    ...
}

public class LocationFollower {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "id", nullable = false)
    public Long id;
    
    @ManyToOne
    @JoinColumn(name="locationId")
    public Location followedLocation;
    
    @ManyToOne
    @JoinColumn(name="followerId")
    public User follower;
    
    @Column(name = "followerSince")
    public Timestamp followerSince;
}

public class Location {
    ...

    @Cascade(value = {CascadeType.DELETE})
    @OneToMany(fetch= FetchType.LAZY)
    @JoinColumn(name="locationId")
    public List<LocationFollower> followers;

    ...
}

我只想删除一个用户。从逻辑上讲,人们会假设连接用户和位置的所有相关“关注者”条目都将被删除。如果我删除一个 Location 条目,同样的假设应该仍然有效。

实际上发生的是 Hibernate 尝试更新(?!?)包含关注者的表,并且由于相关实体(用户或位置)已被发送以供删除,因此尝试设置外键,例如,后跟 null。这将引发异常并突发所有后续操作。

我得到的错误: 服务器上出现未处理的故障。无法执行 JDBC 批量更新; SQL [update locationstofollowers set followerId=null where followerId=?];约束[空];嵌套异常是 org.hibernate.exception.ConstraintViolationException:无法执行 JDBC 批量更新

附言我听说还有另一个级联选项 DELETE_ORPHAN。这个好像已经过时了,我也试了,效果一样。

最佳答案

因为你做了一个双向映射,你必须从两个地方移除对象。这应该有效:

user.followedLocations.remove(aLocation);
session.update(user);
session.delete(aLocation);

关于java - Hibernate中级联删除的问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6009261/

相关文章:

mysql - JPA 如何将 ElementCollection 表的列类型设置为 BLOB

java - Hibernate从数据库读取数据时出错

java - 如何在 Hibernate 拦截器中获取 Hibernate session ?

java - 确保实现静态方法

java - Hibernate 持久方法文档中的 "called outside of transaction"是什么意思

java - Hibernate 抛出奇怪的错误 : Class is not mapped

java - Data Nucleus 带有注释的多对多属性关系

java - 将日期作为参数从 JSP 发送到 servlet

java - JfileChooser 不会显示在 Jpanel 中选择的图像

java - portlet view.jsp 中的单选按钮