org.hibernate.ObjectDeletedException: deleted instance passed to merge: [xxx#<null>]

今天在工作中碰到了这个错误,分析一番发现是代码中的有一段逻辑出现了问题:具体是在List中有若干对象,当遍历时删除了其中的一个对象,而后的语句中竟然还要保存这个对象。有点混乱是吧!!总之是保存了一个已经删除的对象。
下面是转载的有一点相似的地方:
我们在使用hibernate或JPA的一对多、多对一进行删除操作的时候常会出现org.hibernate.ObjectDeletedException: deleted entity passed to  persist: [xxx#<null>]的错误。

 例如:建立deparment(部门)、user(人员)两个实体类:

[java]  view plain copy
  1. package com.yg.bean.user;  
  2.   
  3. import java.util.HashSet;  
  4. import java.util.Set;  
  5.   
  6. import javax.persistence.Column;  
  7. import javax.persistence.Entity;  
  8. import javax.persistence.FetchType;  
  9. import javax.persistence.Id;  
  10. import javax.persistence.OneToMany;  
  11.   
  12. /** 
  13.  * 部门信息实体类 
  14.  * @author: LiChao 
  15.  * date: Nov 6, 2012 -- 3:03:39 PM 
  16.  */  
  17. @Entity  
  18. public class Department {  
  19.   
  20.     /*部门编号*/  
  21.     private String code;  
  22.     /*部门名称*/  
  23.     private String name;  
  24.     /*部门内员工*/  
  25.     private Set<User> users = new HashSet<User>();  
  26.   
  27.     public Department() {}  
  28.     public Department(String code) {  
  29.         this.code = code;  
  30.     }  
  31.     public Department(String code, String name) {  
  32.         this.code = code;  
  33.         this.name = name;  
  34.     }  
  35.   
  36.     @Id @Column(length=12,nullable=false)  
  37.     public String getCode() {  
  38.         return code;  
  39.     }  
  40.     public void setCode(String code) {  
  41.         this.code = code;  
  42.     }  
  43.   
  44.     @Column(length=60,nullable=false)  
  45.     public String getName() {  
  46.         return name;  
  47.     }  
  48.     public void setName(String name) {  
  49.         this.name = name;  
  50.     }  
  51.   
  52.     @OneToMany(mappedBy="dwdm",fetch=FetchType.EAGER)  
  53.     public Set<User> getUsers() {  
  54.         return users;  
  55.     }  
  56.     public void setUsers(Set<User> users) {  
  57.         this.users = users;  
  58.     }  
  59.   
  60.     @Override  
  61.     public int hashCode() {  
  62.         final int prime = 31;  
  63.         int result = 1;  
  64.         result = prime * result + ((code == null) ? 0 : code.hashCode());  
  65.         return result;  
  66.     }  
  67.     @Override  
  68.     public boolean equals(Object obj) {  
  69.         if (this == obj)  
  70.             return true;  
  71.         if (obj == null)  
  72.             return false;  
  73.         if (getClass() != obj.getClass())  
  74.             return false;  
  75.         final Department other = (Department) obj;  
  76.         if (code == null) {  
  77.             if (other.code != null)  
  78.                 return false;  
  79.         } else if (!code.equals(other.code))  
  80.             return false;  
  81.         return true;  
  82.     }  
  83.       
  84. }  
[java]  view plain  copy
  1. <span style="font-size:14px;">package com.yg.bean.user;  
  2.   
  3. import java.util.HashSet;  
  4. import java.util.Set;  
  5.   
  6. import javax.persistence.Column;  
  7. import javax.persistence.Entity;  
  8. import javax.persistence.FetchType;  
  9. import javax.persistence.Id;  
  10. import javax.persistence.OneToMany;  
  11.   
  12. /** 
  13.  * 部门信息实体类 
  14.  * @author: LiChao 
  15.  * date: Nov 6, 2012 -- 3:03:39 PM 
  16.  */  
  17. @Entity  
  18. public class Department {  
  19.   
  20.     /*部门编号*/  
  21.     private String code;  
  22.     /*部门名称*/  
  23.     private String name;  
  24.     /*部门内员工*/  
  25.     private Set<User> users = new HashSet<User>();  
  26.   
  27.     public Department() {}  
  28.     public Department(String code) {  
  29.         this.code = code;  
  30.     }  
  31.     public Department(String code, String name) {  
  32.         this.code = code;  
  33.         this.name = name;  
  34.     }  
  35.   
  36.     @Id @Column(length=12,nullable=false)  
  37.     public String getCode() {  
  38.         return code;  
  39.     }  
  40.     public void setCode(String code) {  
  41.         this.code = code;  
  42.     }  
  43.   
  44.     @Column(length=60,nullable=false)  
  45.     public String getName() {  
  46.         return name;  
  47.     }  
  48.     public void setName(String name) {  
  49.         this.name = name;  
  50.     }  
  51.   
  52.     @OneToMany(mappedBy="dwdm",fetch=FetchType.EAGER)  
  53.     public Set<User> getUsers() {  
  54.         return users;  
  55.     }  
  56.     public void setUsers(Set<User> users) {  
  57.         this.users = users;  
  58.     }  
  59.   
  60.     @Override  
  61.     public int hashCode() {  
  62.         final int prime = 31;  
  63.         int result = 1;  
  64.         result = prime * result + ((code == null) ? 0 : code.hashCode());  
  65.         return result;  
  66.     }  
  67.     @Override  
  68.     public boolean equals(Object obj) {  
  69.         if (this == obj)  
  70.             return true;  
  71.         if (obj == null)  
  72.             return false;  
  73.         if (getClass() != obj.getClass())  
  74.             return false;  
  75.         final Department other = (Department) obj;  
  76.         if (code == null) {  
  77.             if (other.code != null)  
  78.                 return false;  
  79.         } else if (!code.equals(other.code))  
  80.             return false;  
  81.         return true;  
  82.     }  
  83.       
  84. }  
  85. </span>  
[java]  view plain copy
  1. package com.yg.bean.user;  
  2.   
  3. import javax.persistence.CascadeType;  
  4. import javax.persistence.Column;  
  5. import javax.persistence.Id;  
  6. import javax.persistence.JoinColumn;  
  7. import javax.persistence.ManyToOne;  
  8.   
  9. import org.hibernate.annotations.NotFound;  
  10. import org.hibernate.annotations.NotFoundAction;  
  11.   
  12. /** 
  13.  * 系统用户信息实体类 
  14.  * @author: LiChao 
  15.  * date: Nov 6, 2012 -- 3:45:02 PM 
  16.  */  
  17. public class User1 {  
  18.     /*id*/  
  19.     private String id;  
  20.     /*用户名*/  
  21.     private String name;  
  22.     /**/  
  23.     private Integer age;  
  24.     /*部门*/  
  25.     private Department dep;  
  26.       
  27.     @Id @Column(length=6,nullable=false)  
  28.     public String getId() {  
  29.         return id;  
  30.     }  
  31.     public void setId(String id) {  
  32.         this.id = id;  
  33.     }  
  34.     @Column(length=30,nullable=true)  
  35.     public String getName() {  
  36.         return name;  
  37.     }  
  38.     public void setName(String name) {  
  39.         this.name = name;  
  40.     }  
  41.     @Column(nullable=true)  
  42.     public Integer getAge() {  
  43.         return age;  
  44.     }  
  45.     public void setAge(Integer age) {  
  46.         this.age = age;  
  47.     }  
  48.     @ManyToOne(cascade=CascadeType.REFRESH)  
  49.     @JoinColumn(name="dep")  
  50.     @NotFound(action=NotFoundAction.IGNORE)  
  51.     public Department getDep() {  
  52.         return dep;  
  53.     }  
  54.     public void setDep(Department dep) {  
  55.         this.dep = dep;  
  56.     }  
  57. }  
[java]  view plain  copy
  1. <span style="font-size:14px;">package com.yg.bean.user;  
  2.   
  3. import javax.persistence.CascadeType;  
  4. import javax.persistence.Column;  
  5. import javax.persistence.Id;  
  6. import javax.persistence.JoinColumn;  
  7. import javax.persistence.ManyToOne;  
  8.   
  9. import org.hibernate.annotations.NotFound;  
  10. import org.hibernate.annotations.NotFoundAction;  
  11.   
  12. /** 
  13.  * 系统用户信息实体类 
  14.  * @author: LiChao 
  15.  * date: Nov 6, 2012 -- 3:45:02 PM 
  16.  */  
  17. public class User1 {  
  18.     /*id*/  
  19.     private String id;  
  20.     /*用户名*/  
  21.     private String name;  
  22.     /**/  
  23.     private Integer age;  
  24.     /*部门*/  
  25.     private Department dep;  
  26.       
  27.     @Id @Column(length=6,nullable=false)  
  28.     public String getId() {  
  29.         return id;  
  30.     }  
  31.     public void setId(String id) {  
  32.         this.id = id;  
  33.     }  
  34.     @Column(length=30,nullable=true)  
  35.     public String getName() {  
  36.         return name;  
  37.     }  
  38.     public void setName(String name) {  
  39.         this.name = name;  
  40.     }  
  41.     @Column(nullable=true)  
  42.     public Integer getAge() {  
  43.         return age;  
  44.     }  
  45.     public void setAge(Integer age) {  
  46.         this.age = age;  
  47.     }  
  48.     @ManyToOne(cascade=CascadeType.REFRESH)  
  49.     @JoinColumn(name="dep")  
  50.     @NotFound(action=NotFoundAction.IGNORE)  
  51.     public Department getDep() {  
  52.         return dep;  
  53.     }  
  54.     public void setDep(Department dep) {  
  55.         this.dep = dep;  
  56.     }  
  57. }  
  58. </span>  


      当我们在删除user表中的记录的时候就会报我们之前提到的异常,这是什么原因呢?细心的朋友可能注意到了,在depatment实体中department对user为一对多关系,并且加载方式为“立即加载”(fetch=FetchType.EAGER),关键就在这里,你可以简单理解为当你调用了department实体后,就会立即得到对表user的数据的引用,所以你再对user表中的数据经行删除的时候是不被允许的。解决方法我想到了两种:

1、最简单的方法:抓取策略改为懒加载方式(fetch=FetchType.LAZY)。但是这种方法在你调用department.getUsers();后再进行删除user表中记录的操作的时候仍会报相同异常,并且还极有可能报session已关闭异常。

2、比较完美的方法:department.getUsers().clear();为防止session已关闭异常,我们有时候必须将加载策略设为立即加载,怎么完美解决呢?很简单!在你删除user表中数据前先执行department.getUsers().clear();就可以了,你可以理解为:清除对user表数据的引用。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值