1. 程式人生 > >hibernate多對多關係操作

hibernate多對多關係操作

hibernate多對多當中,我們常常希望只刪除一方已及對應的關係,但不想刪除另一方,怎麼樣達到呢? (這裡只提刪除)

表user和表role多對多,中間表user_role(userId,roleId),user是主控方,role是從方,

在spring+hibernate的環境下,使用的是Annotation配置

User.java

@ManyToMany(cascade = {CascadeType.MERGE,CascadeType.PERSIST}, fetch = FetchType.EAGER)
@JoinTable(name = "user_role",

joinColumns = { @JoinColumn(name = "userId",referencedColumnName="userId") },

inverseJoinColumns = { @JoinColumn(name = "roleId",referencedColumnName="roleId") })
 public Set<Role> getRoles() {
  return this.roles;
 }

Role.java

@ManyToMany(cascade = {CascadeType.MERGE,CascadeType.PERSIST}, fetch = FetchType.EAGER,

 mappedBy = "roles")
 public Set<User> getUsers() {
  return this.users;
 }

測試:主控方User刪除,user會被刪除,user_role的中的關係也會被刪除了,但對應的role不會被刪除

@Test
 public void testDelete() {
  User user = userDao.findById(8);
  userDao.delete(user);
 }

測試:從方Role刪除,如果user_role裡面沒有對應的roleId,role可以刪除,user不會被刪除

@Test
 public void testDelete() {
  Role role = roleDao.findById(26);
  roleDao.delete(role); 

}

測試:從方Role刪除,如果user_role裡面有對應的roleId和別的userId關聯,role不能被刪除

@Test
 public void testDelete() {
  Role role = roleDao.findById(26);
  roleDao.delete(role); 

}

會報錯:org.springframework.dao.DataIntegrityViolationException: Could not execute JDBC batch update; nested exception is org.hibernate.exception.ConstraintViolationException: Could not execute JDBC batch update

Caused by: org.hibernate.exception.ConstraintViolationException: Could not execute JDBC batch update


Caused by: java.sql.BatchUpdateException: Cannot delete or update a parent row: a foreign key constraint fails (`hrms`.`user_role`, CONSTRAINT `roleId` FOREIGN KEY (`roleId`) REFERENCES `role` (`roleId`) ON DELETE NO ACTION ON UPDATE NO ACTION)

解決方案:在資料庫裡更改user_role表結構,就是新增約束,就新增roleId的刪除時進行級聯操作

ALTER TABLE `hrms`.`user_role`

  ADD CONSTRAINT `roleId`

  FOREIGN KEY (`roleId` )

  REFERENCES `hrms`.`role` (`roleId` )

  ON DELETE CASCADE;

測試:從方Role刪除,如果user_role裡面有對應的roleId,現在role可以刪除,user_role裡面對應的關係也會被刪除,但對應的user不會被刪除,達到我們想要的效果

@Test
 public void testDelete() {
  Role role = roleDao.findById(26);
  roleDao.delete(role); 

}