JPA+Hibernate出错java.lang.IllegalArgumentException: Removing a detached instance

JPA+Hibernate Junit4做批量删除时出错:

批量删除方法如下:

private EntityManager em

 

	/**
	 * 批量删除实体
	 * 可实体批量删除操作,在一个transaction中完成
	 * 任何Exception发生,全部更新操作回滚
	 * @param entityClass 实体类
	 * @param entityids 实体id数组
	 */
	public void batchDelete(List<T> entities){
		for(int i = 0; i<entities.size(); i++){
			em.remove(entities.get(i));
		}
	}

 junit测试出现以下错误:

java.lang.IllegalArgumentException: Removing a detached instance com.agiliti.bean.person.Person#47

..................

原因:

em调用remove时,Hibernate仍然还处于“detach”状态,在Hibernate文档中关于detach叙述:

Detached - a detached instance is an object that has been persistent, but its Session has been closed. The reference to the object is still valid, of course, and the detached instance might even be modified in this state. A detached instance can be reattached to a new Session at a later point in time, making it (and all the modifications) persistent again. 

此时,Session已经关闭,但引用仍然存在(换句话说,heap里的对象没有了)。所以此时必须再次产生一个Session(在heap里产生对象):

解决方法之一——在删除之前把这个Detached instance绑定到当前的Sesssion,在用当前Sesssion删除此instance。getEntityManager()提供merge方法实现:

 

public void batchDelete(List<T> entities){
		for(int i = 0; i<entities.size(); i++){
			em.remove(em.merge(entities.get(i)));
		}
	}
 

 

请注意:如果写成:

仍然错误写法

	public void batchDelete(List<T> entities){
		for(int i = 0; i<entities.size(); i++){
			em.merge(entities.get(i));
                        em.remove(entities.get(i));
		}
	}

 原因是执行完merge还是detached, merge后返回的新对象才是允许删除的。

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值