Hibernate(JPA)多对多(ManyToMany)关联映射不完美之处 - 编程入门网
Hibernate(JPA)多对多(ManyToMany)关联映射不完美之处时间:2012-01-03 blogjava 心梦帆影近来,在做的一个NewsMS项目中,需要用到多对多关联映射,以下是项目中用到的两个实体类:用户类User和角色类Role,它们之间是多对多的关系。 //用户表 @Entity @Table(name="rong_user") public class User{ //省略其它内容 private Set<Role> roles = new LinkedHashSet<Role>(); //角色集合 @ManyToMany(cascade = {CascadeType.PERSIST, CascadeType.MERGE}) @JoinTable(name = "rong_user_role", joinColumns = { @JoinColumn(name ="user_id" )}, inverseJoinColumns = { @JoinColumn(name = "role_id") }) @OrderBy("id") public Set<Role> getRoles() { return roles; } public void setRoles(Set<Role> roles) { this.roles = roles; } } //角色表 @Entity @Table(name="rong_role") public class Role{ //省略其它内容 private Set<User> user = new LinkedHashSet<User>(); //用户集合 @ManyToMany(cascade = {CascadeType.PERSIST, CascadeType.MERGE}, mappedBy = "roles", fetch = FetchType.LAZY) public Set<User> getUser() { return user; } public void setUser(Set<User> user) { this.user = user; } } 这两个生成数据库中的三个表,分别是rong_user, rong_role和一个中间表rong_user_role。 Hibernate和JPA控制关联关系的,只能是一方,不能双方控制的,上面的程序中,我通过在Role类中设置mappedBy="roles"来设置由User来控制关系, 这样,问题就出现了:当我在要删除角色Role时,如果没有用户拥有这个角色的话,就能成功删除;如果有用户拥有这个角色的时候,就不能删除,会抛以下异常: 12:53:33,125 WARN JDBCExceptionReporter:100 - SQL Error: 1451, SQLState: 23000 12:53:33,125 ERROR JDBCExceptionReporter:101 - Cannot delete or update a parent row: a foreign key constraint fails (`newsms/rong_user_role`, CONSTRAINT `FKF1698421A337A5FA` FOREIGN KEY (`role_id`) REFERENCES `rong_role` (`id`)) 12:53:33,171 ERROR AbstractFlushingEventListener:324 - Could not synchronize database state with session org.hibernate.exception.ConstraintViolationException: Could not execute JDBC batch update Hibernate(JPA)多对多(ManyToMany)关联映射不完美之处(2)时间:2012-01-03 blogjava 心梦帆影/****堆栈信息略****/ Caused by: java.sql.BatchUpdateException: Cannot delete or update a parent row: a foreign key constraint fails (`newsms/rong_user_role`, CONSTRAINT `FKF1698421A337A5FA` FOREIGN KEY (`role_id`) REFERENCES `rong_role` (`id`)) /******堆栈信息略*****/ 当我设置成单向关系映射时,即把Role类中,Set<User>信息去掉,这样,也不能删,原因也是说有外键约束!怎么办? 苦恼了好几天,最后,只能归于Hibernate(JPA)的多对多关联映射设计得有点不符实际!就像上面我说的例子,有人选了某角色,就不能删掉该角色。还有一种做法是,在Role类中: @ManyToMany(cascade = {CascadeType.PERSIST, CascadeType.MERGE,CascadeType.REMOVE}, mappedBy = "roles", fetch = FetchType.LAZY) public Set<User> getUser() { return user; } 即加多一个“CascadeType.REMOVE”,这样能把角色Role给删掉了,但连拥有该角色的所有用户User也被级联删掉了。这样来看,某个用户拥有许多角色,就因为其中有这一个角色,就被级联删了整个自己,那不是很冤枉。这也不符合实际! 个人认为,Hibernate(JPA)在设置多对多关联映射时,应该有做法能使得双方都能控制关联关系才好,才符合实际吧!但事实上,好像还没有发现有Hibernate(JPA)这种能力! |
凌众科技专业提供服务器租用、服务器托管、企业邮局、虚拟主机等服务,公司网站:http://www.lingzhong.cn 为了给广大客户了解更多的技术信息,本技术文章收集来源于网络,凌众科技尊重文章作者的版权,如果有涉及你的版权有必要删除你的文章,请和我们联系。以上信息与文章正文是不可分割的一部分,如果您要转载本文章,请保留以上信息,谢谢! |