Hibernate双向ManyToMany删除问题

时间:2013-03-01 10:32:59

标签: hibernate many-to-many hibernate-mapping

在我的项目中,我有用户和公司的实体:

@Entity
@Table(name = "users")
public class UserDetails {

    @Id
    @GeneratedValue
    @Column(name = "user_id")
    private int id;

    @Column(name = "first_name")
    @NotEmpty
    @Size(min = 2, max = 20)
    private String firstName;

    @ManyToMany(cascade = CascadeType.REFRESH)
    @JoinTable(name = "users_companies",
            joinColumns = @JoinColumn(name = "user_id"),
            inverseJoinColumns = @JoinColumn(name = "company_id"))
    private Set<CompanyDetails> userCompanies = new HashSet();

    //getters and setters of course...
}

@Entity
@Table(name = "companies")
public class CompanyDetails {
    @Id
    @GeneratedValue
    @Column(name = "company_id")
    private int id;

    @Column(name = "name")
    @NotEmpty
    @Size(min = 1, max = 255)
    private String name;

    @ManyToMany(mappedBy = "userCompanies")
    private Set<UserDetails> companyUsers = new HashSet();

}

我在视图中将用户分配给公司,然后尝试删除。删除用户时,一切正常 - 用户删除,“users_companies”表中的记录也被删除,公司仍然存在(必要时)。但是当我尝试删除一家公司时,我的堆栈跟踪有以下根本原因:

com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Cannot delete or update a parent row: a foreign key constraint fails (`d_torianik/users_companies`, CONSTRAINT `FK447D806437A764EB` FOREIGN KEY (`company_id`) REFERENCES `companies` (`company_id`))

你能帮我解决这个问题吗?谢谢。

2 个答案:

答案 0 :(得分:4)

我知道这是旧的,但它可能对某人有所帮助......我试图做同样的事情 - 从每个主表中删除首先在连接表中删除引用的记录然后从主表中删除记录。 benzonico的帖子是有效的,但有一种更简单的方法可以做到这一点(无需自己从连接表中删除记录)。公司表的映射也需要更改为主表(不要使用mappedBy):

@Entity
@Table(name = "companies")
public class CompanyDetails {
    @Id
    @GeneratedValue
    @Column(name = "company_id")
    private int id;

    @Column(name = "name")
    @NotEmpty
    @Size(min = 1, max = 255)
    private String name;

    @ManyToMany(cascade = {CascadeType.PERSIST, CascadeType.MERGE})
    @JoinTable(name = "users_companies",
    joinColumns = {@JoinColumn(name = "company_id")},
    inverseJoinColumns = @JoinColumn(name = "user_id"))
    private Set<UserDetails> companyUsers = new HashSet();

}

这应该可以解决问题。现在每当你删除公司时,Hibernate将首先删除users_companies中的记录,然后它将删除公司本身。更多信息:http://www.codereye.com/2009/06/hibernate-bi-directional-many-to-many.html

答案 1 :(得分:1)

您必须在实体CascadeType.REMOVE的属性Cascade的{​​{1}}注释中添加companyUsers

[评论后编辑]

对不起,我在答案中错过了一件事,那就是很多人。所以级联删除不起作用。那么问题是负责关系的是UserDetails类。这就是为什么它在一种方式而不是在另一种方式上工作的原因。在删除公司之前,您可能必须从companyUsers set的每个UserDetails中设置的userCompanies中删除该公司。