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)

请大家帮忙看看是哪里的问题,谢谢!
...全文
153 13 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
13 条回复
切换为时间正序
请发表友善的回复…
发表回复
暗然的白天 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的指教,分给你了,谢谢


扁鵲東南飛 2011-01-27
  • 打赏
  • 举报
回复
为什么这样写呢?
你先根据 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和事务的问题,但不是特别明白,请教下大家,谢谢啦!
HIBERNATE - 符合Java习惯的关系数据库持久化 Hibernate参考文档 3.2 -------------------------------------------------------------------------------- 目录 前言 1. 翻译说明 2. 版权声明 1. Hibernate入门 1.1. 前言 1.2. 第一部分 - 第一个Hibernate应用程序 1.2.1. 第一个class 1.2.2. 映射文件 1.2.3. Hibernate配置 1.2.4. 用Ant构建 1.2.5. 启动和辅助类 1.2.6. 加载并存储对象 1.3. 第二部分 - 关联映射 1.3.1. 映射Person类 1.3.2. 单向Set-based的关联 1.3.3. 使关联工作 1.3.4. 值类型的集合 1.3.5. 双向关联 1.3.6. 使双向连起来 1.4. 第三部分 - EventManager web应用程序 1.4.1. 编写基本的servlet 1.4.2. 处理与渲染 1.4.3. 部署与测试 1.5. 总结 2. 体系结构(Architecture) 2.1. 概况(Overview) 2.2. 实例状态 2.3. JMX整合 2.4. 对JCA的支持 2.5. 上下文相关的(Contextual)Session 3. 配置 3.1. 可编程的配置方式 3.2. 获得SessionFactory 3.3. JDBC连接 3.4. 可选的配置属性 3.4.1. SQL方言 3.4.2. 外连接抓取(Outer Join Fetching) 3.4.3. 二进制流 (Binary Streams) 3.4.4. 二级缓存与查询缓存 3.4.5. 查询语言中的替换 3.4.6. Hibernate的统计(statistics)机制 3.5. 日志 3.6. 实现NamingStrategy 3.7. XML配置文件 3.8. J2EE应用程序服务器的集成 3.8.1. 事务策略配置 3.8.2. JNDI绑定的SessionFactory 3.8.3. 在JTA环境下使用Current Session context (当前session上下文)管理 3.8.4. JMX部署 4. 持久化类(Persistent Classes) 4.1. 一个简单的POJO例子 4.1.1. 实现一个默认的(即无参数的)构造方法(constructor) 4.1.2. 提供一个标识属性(identifier property)(可选) 4.1.3. 使用非final的类 (可选) 4.1.4. 为持久化字段声明访问器(accessors)和是否可变的标志(mutators)(可选) 4.2. 实现继承(Inheritance) 4.3. 实现equals()和hashCode() 4.4. 动态模型(Dynamic models) 4.5. 元组片断映射(Tuplizers) 5. 对象/关系数据库映射基础(Basic O/R Mapping) 5.1. 映射定义(Mapping declaration) 5.1.1. Doctype 5.1.2. hibernate-mapping 5.1.3. class 5.1.4. id 5.1.5. composite-id 5.1.6. 鉴别器(discriminator) 5.1.7. 版本(version)(可选) 5.1.8. timestamp (可选) 5.1.9. property 5.1.10. 多对一(many-to-one) 5.1.11. 一对一 5.1.12. 自然ID(natural-id) 5.1.13. 组件(component), 动态组件(dynamic-component) 5.1.14. properties 5.1.15. 子类(subclass) 5.1.16. 连接的子类(joined-subclass) 5.1.17. 联合子类(union-subclass) 5.1.18. 连接(join) 5.1.19. 键(key) 5.1.20. 字段和规则元素(column and formula elements) 5.1.21. 引用(import) 5.1.22. any 5.2. Hibernate 的类型 5.2.1. 实体(Entities)和值(values) 5.2.2. 基本值类型 5.2.3. 自定义值类型 5

81,122

社区成员

发帖
与我相关
我的任务
社区描述
Java Web 开发
社区管理员
  • Web 开发社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧