Hibernate中级联删除的问题

时间:2011-05-15 15:16:56

标签: 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;

    ...
}

我想要的只是删除用户。从逻辑上讲,人们会假设连接用户和位置的所有相关“关注者”条目都将被删除。如果删除位置条目,相同的假设应该保持不变。

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

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

P.S。我听说还有另一个级联选项DELETE_ORPHAN。这似乎已被弃用,即使我也尝试过,效果也一样。

2 个答案:

答案 0 :(得分:1)

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

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

答案 1 :(得分:0)

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