org.hibernate.ObjectDeletedException: deleted instance passed to merge: [xxx#<null>]
2015-04-16 17:29
357 查看
今天在工作中碰到了这个错误,分析一番发现是代码中的有一段逻辑出现了问题:具体是在List中有若干对象,当遍历时删除了其中的一个对象,而后的语句中竟然还要保存这个对象。有点混乱是吧!!总之是保存了一个已经删除的对象。
下面是转载的有一点相似的地方:
转载自:http://blog.csdn.net/lichao3459/article/details/9225235
我们在使用hibernate或JPA的一对多、多对一进行删除操作的时候常会出现org.hibernate.ObjectDeletedException: deleted entity passed to persist: [xxx#<null>]的错误。
例如:建立deparment(部门)、user(人员)两个实体类:
[java] view plaincopyprint?
package com.yg.bean.user;
import java.util.HashSet;
import java.util.Set;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.Id;
import javax.persistence.OneToMany;
/**
* 部门信息实体类
* @author: LiChao
* date: Nov 6, 2012 -- 3:03:39 PM
*/
@Entity
public class Department {
/*部门编号*/
private String code;
/*部门名称*/
private String name;
/*部门内员工*/
private Set<User> users = new HashSet<User>();
public Department() {}
public Department(String code) {
this.code = code;
}
public Department(String code, String name) {
this.code = code;
this.name = name;
}
@Id @Column(length=12,nullable=false)
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
@Column(length=60,nullable=false)
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@OneToMany(mappedBy="dwdm",fetch=FetchType.EAGER)
public Set<User> getUsers() {
return users;
}
public void setUsers(Set<User> users) {
this.users = users;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((code == null) ? 0 : code.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
final Department other = (Department) obj;
if (code == null) {
if (other.code != null)
return false;
} else if (!code.equals(other.code))
return false;
return true;
}
}
[java] view plaincopyprint?
package com.yg.bean.user;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import org.hibernate.annotations.NotFound;
import org.hibernate.annotations.NotFoundAction;
/**
* 系统用户信息实体类
* @author: LiChao
* date: Nov 6, 2012 -- 3:45:02 PM
*/
public class User1 {
/*id*/
private String id;
/*用户名*/
private String name;
/**/
private Integer age;
/*部门*/
private Department dep;
@Id @Column(length=6,nullable=false)
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
@Column(length=30,nullable=true)
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Column(nullable=true)
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
@ManyToOne(cascade=CascadeType.REFRESH)
@JoinColumn(name="dep")
@NotFound(action=NotFoundAction.IGNORE)
public Department getDep() {
return dep;
}
public void setDep(Department dep) {
this.dep = dep;
}
}
当我们在删除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表数据的引用。
下面是转载的有一点相似的地方:
转载自:http://blog.csdn.net/lichao3459/article/details/9225235
我们在使用hibernate或JPA的一对多、多对一进行删除操作的时候常会出现org.hibernate.ObjectDeletedException: deleted entity passed to persist: [xxx#<null>]的错误。
例如:建立deparment(部门)、user(人员)两个实体类:
[java] view plaincopyprint?
package com.yg.bean.user;
import java.util.HashSet;
import java.util.Set;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.Id;
import javax.persistence.OneToMany;
/**
* 部门信息实体类
* @author: LiChao
* date: Nov 6, 2012 -- 3:03:39 PM
*/
@Entity
public class Department {
/*部门编号*/
private String code;
/*部门名称*/
private String name;
/*部门内员工*/
private Set<User> users = new HashSet<User>();
public Department() {}
public Department(String code) {
this.code = code;
}
public Department(String code, String name) {
this.code = code;
this.name = name;
}
@Id @Column(length=12,nullable=false)
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
@Column(length=60,nullable=false)
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@OneToMany(mappedBy="dwdm",fetch=FetchType.EAGER)
public Set<User> getUsers() {
return users;
}
public void setUsers(Set<User> users) {
this.users = users;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((code == null) ? 0 : code.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
final Department other = (Department) obj;
if (code == null) {
if (other.code != null)
return false;
} else if (!code.equals(other.code))
return false;
return true;
}
}
<span style="font-size:14px;">package com.yg.bean.user; import java.util.HashSet; import java.util.Set; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.FetchType; import javax.persistence.Id; import javax.persistence.OneToMany; /** * 部门信息实体类 * @author: LiChao * date: Nov 6, 2012 -- 3:03:39 PM */ @Entity public class Department { /*部门编号*/ private String code; /*部门名称*/ private String name; /*部门内员工*/ private Set<User> users = new HashSet<User>(); public Department() {} public Department(String code) { this.code = code; } public Department(String code, String name) { this.code = code; this.name = name; } @Id @Column(length=12,nullable=false) public String getCode() { return code; } public void setCode(String code) { this.code = code; } @Column(length=60,nullable=false) public String getName() { return name; } public void setName(String name) { this.name = name; } @OneToMany(mappedBy="dwdm",fetch=FetchType.EAGER) public Set<User> getUsers() { return users; } public void setUsers(Set<User> users) { this.users = users; } @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + ((code == null) ? 0 : code.hashCode()); return result; } @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (getClass() != obj.getClass()) return false; final Department other = (Department) obj; if (code == null) { if (other.code != null) return false; } else if (!code.equals(other.code)) return false; return true; } } </span>
[java] view plaincopyprint?
package com.yg.bean.user;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import org.hibernate.annotations.NotFound;
import org.hibernate.annotations.NotFoundAction;
/**
* 系统用户信息实体类
* @author: LiChao
* date: Nov 6, 2012 -- 3:45:02 PM
*/
public class User1 {
/*id*/
private String id;
/*用户名*/
private String name;
/**/
private Integer age;
/*部门*/
private Department dep;
@Id @Column(length=6,nullable=false)
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
@Column(length=30,nullable=true)
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Column(nullable=true)
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
@ManyToOne(cascade=CascadeType.REFRESH)
@JoinColumn(name="dep")
@NotFound(action=NotFoundAction.IGNORE)
public Department getDep() {
return dep;
}
public void setDep(Department dep) {
this.dep = dep;
}
}
<span style="font-size:14px;">package com.yg.bean.user; import javax.persistence.CascadeType; import javax.persistence.Column; import javax.persistence.Id; import javax.persistence.JoinColumn; import javax.persistence.ManyToOne; import org.hibernate.annotations.NotFound; import org.hibernate.annotations.NotFoundAction; /** * 系统用户信息实体类 * @author: LiChao * date: Nov 6, 2012 -- 3:45:02 PM */ public class User1 { /*id*/ private String id; /*用户名*/ private String name; /**/ private Integer age; /*部门*/ private Department dep; @Id @Column(length=6,nullable=false) public String getId() { return id; } public void setId(String id) { this.id = id; } @Column(length=30,nullable=true) public String getName() { return name; } public void setName(String name) { this.name = name; } @Column(nullable=true) public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } @ManyToOne(cascade=CascadeType.REFRESH) @JoinColumn(name="dep") @NotFound(action=NotFoundAction.IGNORE) public Department getDep() { return dep; } public void setDep(Department dep) { this.dep = dep; } } </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表数据的引用。
相关文章推荐
- org.hibernate.ObjectDeletedException: deleted instance passed to merge: [xxx#<null>]
- org.hibernate.ObjectDeletedException: deleted entity passed to persist: [xxx#<null>]
- org.hibernate.ObjectDeletedException: deleted instance passed to merge
- org.hibernate.MappingException: An AnnotationConfiguration instance is required to use <mapping class="Bbs"/>
- org.hibernate.PersistentObjectException: detached entity passed to persist
- javax.persistence.PersistenceException: org.hibernate.PersistentObjectException: detached entity passed to persist:
- jpa遇到的 org.hibernate.PersistentObjectException: detached entity passed to persis
- [hibernate异常]org.hibernate.PersistentObjectException: detached entity passed to persist异常
- org.hibernate.HibernateException: identifier of an instance of XXX was altered from X to X
- org.hibernate.PersistentObjectException: detached entity passed to persist异常
- org.hibernate.PersistentObjectException: detached entity passed to persist: cn.yjj.oa.entity.Organization
- org.hibernate.HibernateException: identifier of an instance of XXX was altered from X to X
- org.hibernate.PersistentObjectException: detached entity passed to persist异常
- jpa遇到的 org.hibernate.PersistentObjectException: detached entity passed to persist异常
- org.hibernate.MappingException: An AnnotationConfiguration instance is required to use <mapping clas
- org.hibernate.PersistentObjectException: detached entity passed to persist:
- 遇到错误 org.hibernate.HibernateException: identifier of an instance of XXX was altered from X to X 将int
- org.hibernate.PersistentObjectException: detached entity passed to persist
- org.hibernate.PersistentObjectException: detached entity passed to persist:报错解决方法
- org.hibernate.PersistentObjectException: detached entity passed to persist异常