org.hibernate.ObjectDeletedException: deleted entity passed to persist: [xxx#<null>]

       我们在使用hibernate或JPA的一对多、多对一进行删除操作的时候常会出现org.hibernate.ObjectDeletedException: deleted entity passed to persist: [xxx#<null>]的错误,这是怎么引起的呢?又该怎么解决?在这里说说我自己的看法,欢迎不同见解。

       以使用JPA+Spring为例,建立deparment(部门)、user(人员)两个实体类:

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;
	}
	
}
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表数据的引用。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值