【问题标题】:Problems with cascading deletion in HibernateHibernate中级联删除的问题
【发布时间】:2011-08-25 22:33:59
【问题描述】:

这个问题已经被问过无数次了,但我没有看到满意的答案,所以我再问一次。

想象以下情况:

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 尝试更新(?!?)包含关注者的表,并且由于相关实体(用户或位置)已被发送删除,因此尝试设置外键,例如,后跟空。这会引发异常并爆破所有后续操作。

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

附:我听说还有另一个级联选项 DELETE_ORPHAN。这似乎被弃用了,即使我也尝试过,效果是一样的。

【问题讨论】:

  • 很好的问题。遗憾的是,这方面的讨论并不多。

标签: java hibernate orm cascading-deletes


【解决方案1】:

由于您已经进行了双向映射,因此您必须从两个位置移除对象。这应该有效:

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

【讨论】:

  • 这会产生耦合对吧。
  • 不会,映射已经以双向方式完成,这里的问题是位置中的用户对象已被映射为非空..这导致了问题......问题也可以通过取消设置该字段的 not null 属性来修复...
  • 效果很好。谢谢阿南莎!我希望@xantrus 接受这个答案并将其关闭。
【解决方案2】:

你应该设置@JoinColumn(name="followerId", insertable = false, updatable = false)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-10-11
    • 2012-08-16
    • 2011-12-31
    • 1970-01-01
    • 2014-11-16
    • 2013-01-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多