hibernate批量删除时出现的问题

gimm667 2011-01-26 08:12:30
以下是我的批量删除的代码:
String[] studentIDs = request.getParameterValues("VoteOption1");
Collection entities = new ArrayList();
for (int i = 0; i < studentIDs.length; i++) {
T_student student = t_studentDAO.read(Integer.parseInt(studentIDs[i]));

entities.add(student);
}
t_studentDAO.deleteAll(entities);


以下是进行操作时出现的异常信息:
严重: Servlet.service() for servlet action threw exception
org.hibernate.HibernateException: Illegal attempt to associate a collection with two open sessions
at org.hibernate.collection.AbstractPersistentCollection.setCurrentSession(AbstractPersistentCollection.java:410)
at org.hibernate.event.def.OnUpdateVisitor.processCollection(OnUpdateVisitor.java:40)
at org.hibernate.event.def.AbstractVisitor.processValue(AbstractVisitor.java:101)
at org.hibernate.event.def.AbstractVisitor.processValue(AbstractVisitor.java:61)

请大家帮忙看看是哪里的问题,谢谢!
...全文
88 点赞 收藏 13
写回复
13 条回复
切换为时间正序
当前发帖距今超过3年,不再开放新的回复
发表回复
暗然的白天 2011-01-27
read方法
getSession().flush();
getSession().clear();
getSession().close();
如果用spring了就不要在开session了,这样写不好,还有你那是一个循环查询的,而且每次只查一个,麻烦。
既然你已经得到主键了,写hql吧用IN关键字来查。
回复
zn85600301 2011-01-27
read方法实现是:
public T read(PK id) {
return (T) getSession().get(type, id);
}

将这个改成
String hql ="from T_student where id ="+id+"";
this.getHibernateTemplate().find(hql);
试试
回复
gimm667 2011-01-27
沉了么,大家帮帮忙啊
回复
gimm667 2011-01-27
多谢,结贴散分
回复
暗然的白天 2011-01-27
[Quote=引用 7 楼 gimm667 的回复:]
引用 6 楼 chenhao1208 的回复:
read方法
getSession().flush();
getSession().clear();
getSession().close();
如果用spring了就不要在开session了,这样写不好,还有你那是一个循环查询的,而且每次只查一个,麻烦。
既然你已经得到主键了,写hql吧用IN关键字来查。


谢谢,'如果用spr……
[/Quote]
也不能说不好,这个意思。交给spring管理能避免一些忘记链接关闭一些问题
回复
gimm667 2011-01-27
[Quote=引用 6 楼 chenhao1208 的回复:]
read方法
getSession().flush();
getSession().clear();
getSession().close();
如果用spring了就不要在开session了,这样写不好,还有你那是一个循环查询的,而且每次只查一个,麻烦。
既然你已经得到主键了,写hql吧用IN关键字来查。
[/Quote]

根据chenhao1208的提示,最终的解决办法是这样的
Collection<T_student> entities = t_studentDAO.selectAll(ids);
t_studentDAO.deleteAll(entities);

@Override
public Collection<T_student> selectAll(String[] ids) {
return getSession().createQuery("from T_student where ID in (:ids)").setParameterList("ids", ids).list();

}

@Override
public void deleteAll(Collection<T> entities) {
this.getHibernateTemplate().deleteAll(entities);
}

因为T_student和其它任职表和培训表是有关联关系的,所以要删除必须先查出T_student对象,再删除才能删除T_student对象和对应的关联表信息,因此不能使用#10楼zhangliangming_87的方式

感谢#6楼chenhao1208的指教,分给你了,谢谢


回复
为什么这样写呢?
你先根据 id 来查询到所要删除的 记录。然后把这些记录全部读取了。读取的时候用了打开session对象。

然后把这些对象删除,又打开一个session ,但是此前那个session 还没关闭,根据这个推测的(Illegal attempt to associate a collection with two open sessions)


为什么不直接根据 所得的id,直接删除呢?这样感觉效率还高。 不必要先查询出来然后再去删除了。

String[] studentIDs = request.getParameterValues("VoteOption1");
Collection entities = new ArrayList();
for (int i = 0; i < studentIDs.length; i++) {
//T_student student = t_studentDAO.read(Integer.parseInt(studentIDs[i]));
//entities.add(student);
t_studentDAO.deleteById(Integer.parseInt(studentIDs[i]));
}
deleteById();重新写这个方法。这个方法自己写应该很简单。就是根据id删除记录。

回复
君望永远 2011-01-27
还是开个事务吧
回复
stupid_ks 2011-01-27
把你的t_studentDAO中调用到的方法列出来
回复
gimm667 2011-01-27
[Quote=引用 6 楼 chenhao1208 的回复:]
read方法
getSession().flush();
getSession().clear();
getSession().close();
如果用spring了就不要在开session了,这样写不好,还有你那是一个循环查询的,而且每次只查一个,麻烦。
既然你已经得到主键了,写hql吧用IN关键字来查。
[/Quote]

谢谢,'如果用spring了就不要在开session了,这样写不好'这句啥意思?
回复
gimm667 2011-01-26
就是啊
回复
风影萧诺 2011-01-26
怎么没有高手给解答啊!
回复
gimm667 2011-01-26
t_studentDAO我写的接口,
read方法实现是:
public T read(PK id) {
return (T) getSession().get(type, id);
}
deleteAll方法实现是:
public void deleteAll(Collection<T> entities) {
this.getHibernateTemplate().deleteAll(entities);
}

感觉应该是session和事务的问题,但不是特别明白,请教下大家,谢谢啦!
回复
相关推荐
发帖
Web 开发
创建于2007-09-28

8.0w+

社区成员

Java Web 开发
申请成为版主
帖子事件
创建了帖子
2011-01-26 08:12
社区公告
暂无公告