java – Hibernate多对多删除关系
发布时间:2020-12-14 23:20:58 所属栏目:Java 来源:网络整理
导读:我有一个hibernate多对多关系的问题:当我从我的集合中删除一个项目时,它不会在我的数据库中删除.我知道有很多类似的问题,但我没有通过阅读来修复我的问题. 我已经为它编写了一个JUnit测试用例.我的协会是建筑物和用户之间: @Testpublic void testBuildingM
我有一个hibernate多对多关系的问题:当我从我的集合中删除一个项目时,它不会在我的数据库中删除.我知道有很多类似的问题,但我没有通过阅读来修复我的问题.
我已经为它编写了一个JUnit测试用例.我的协会是建筑物和用户之间: @Test public void testBuildingManyToMany(){ //Create 2 buildings Building building = createBuilding("b1"); Building building2 = createBuilding("b2"); //Create 1 user User user = createUser("u1"); //Associate the 2 buildings to that user user.getBuildings().add(building); building.getUsers().add(user); user.getBuildings().add(building2); building2.getUsers().add(user); userController.save(user); user = userController.retrieve(user.getId()); Assert.assertEquals(2,user.getBuildings().size());//Test OK //Test 1: remove 1 building from the list user.getBuildings().remove(building); building.getUsers().remove(user); userController.save(user); //Test 2: clear and add //user.getBuildings().clear(); //user.getBuildings().add(building); //userController.save(user); //user = userController.retrieve(user.getId()); //Assert.assertEquals(1,user.getBuildings().size()); } 这是我得到的错误: ... Hibernate: insert into building_useraccount (userid,buildingid) values (?,?) Hibernate: insert into building_useraccount (userid,?) Hibernate: delete from building_useraccount where userid=? and buildingid=? Hibernate: insert into building_useraccount (userid,?) 4113 [main] WARN org.hibernate.util.JDBCExceptionReporter - SQL Error: 23505,SQLState: 23505 4113 [main] ERROR org.hibernate.util.JDBCExceptionReporter - Unique index or primary key violation: "PRIMARY_KEY_23 ON PUBLIC.BUILDING_USERACCOUNT(BUILDINGID,USERID) VALUES ( /* key:0 */ 201,201)"; SQL statement: insert into building_useraccount (userid,?) [23505-176] 当我评论“测试1”并取消注释“测试2”行时,我发出以下错误: junit.framework.AssertionFailedError: Expected :1 Actual :2 这是我的hbm.xml类: <hibernate-mapping default-lazy="true"> <class name="my.model.pojo.Building" table="building"> <cache usage="read-write" /> <id name="id" column="id" type="java.lang.Long"> <generator class="sequence"> <param name="sequence">building_id_sequence</param> </generator> </id> <property name="name" type="java.lang.String" column="name" not-null="true" /> ... <set name="users" cascade="none" lazy="true" inverse="true" table="building_useraccount"> <key column="buildingid" /> <many-to-many class="my.model.pojo.User" column="userid" /> </set> </class> </hibernate-mapping> 和 <hibernate-mapping default-lazy="true"> <class name="my.model.pojo.User" table="useraccount"> <cache usage="read-write" /> <id name="id" column="id" type="java.lang.Long"> <generator class="sequence"> <param name="sequence">useraccount_id_sequence</param> </generator> </id> <property name="login" type="java.lang.String" column="login" not-null="true" unique="true" length="40" /> ... <set name="buildings" cascade="none" lazy="false" fetch="join" table="building_useraccount"> <key column="userid" /> <many-to-many class="my.model.pojo.Building" column="buildingid" /> </set> </class> </hibernate-mapping> 和班级 public class User implements Serializable,Identifiable { private static final long serialVersionUID = 1L; private int hashCode; private Long id; private String login; private Set<Building> buildings = new HashSet<Building>(); public boolean equals(Object value) { if (value == this) return true; if (value == null || !(value instanceof User)) return false; if (getId() != null && getId().equals(((User) value).getId())) return true; return super.equals(value); } public int hashCode() { if (hashCode == 0) { hashCode = (getId() == null) ? super.hashCode() : new HashCodeBuilder().append(getId()).toHashCode(); } return hashCode; } /* Getter / Setter ... */ 和 public class BuildingBase implements Serializable,Identifiable { private static final long serialVersionUID = 1L; private int hashCode; private Long id; private String name; private Set<User> users = new HashSet<User>(); public boolean equals(Object value) { if (value == this) return true; if (value == null || !(value instanceof Building)) return false; if (getId() != null && getId().equals(((Building) value).getId())) return true; return super.equals(value); } public int hashCode() { if (hashCode == 0) { hashCode = (getId() == null) ? super.hashCode() : new HashCodeBuilder().append(getId()).toHashCode(); } return hashCode; } /* Getter / Setter ... */ 编辑:为事务添加userController实现 @Transactional(readOnly = false,propagation = Propagation.REQUIRED) public User save(User user) throws ServiceException { validate(user);//Validation stuffs return userDAO.update(user); } userDAO: public class UserDAOImpl extends HibernateDAOImpl<User> implements UserDAO { } 而HibernateDAOImpl: public class HibernateDAOImpl<T> implements DAO<T> { public T update(T entity) { return executeAndCreateSessionIfNeeded(new HibernateAction<T>() { @Override public T execute(Session session) { return (T) session.merge(entity); } }); } protected <E> E executeAndCreateSessionIfNeeded(HibernateAction<E> action) { Session session = null; try { session = sessionFactory.getCurrentSession(); return executeAction(action,session); } finally { if (session != null) { session.close(); } } } } 解决方法
CascadeType.REMOVE
doesn’t have sense for many-to-many associations因为,当设置在两侧时,它可以触发父母和孩子之间以及父母之间的链删除.如果您只在父级设置它,当一些其他父级仍引用删除子级时,您可能会遇到问题.
引用Hibernate docs:
(编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |