精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2007-03-16
Illegal attempt to associate a collection with two open sessions; nested exception is org.hibernate.HibernateException: Illegal attempt to associate a collection with two open sessions 我感觉就是 一个 1:n 关系中,比如 论坛的主题和论坛的回复 如果在 一个 controller 方法中, 即想修改 主题的“标题”字段 ,又想修改 回复的“内容”字段 , 然后同时 调用doSave(主题) 和 doSave(回复) ,就会报这个异常。 下面是我 1 对应 的 hbm.xml文件中 相关代码 <set name="backs" table="app_forum_topic_back" lazy="true" cascade="all" inverse="true"> <key column="parentId"/> <one-to-many class="org.appfuse.model.ForumTopicBack"/> </set> 我不清楚 这样的需求 不 同时 调用doSave(主题) 和 doSave(回复) 还有什么别的办法? 大家怎么解决这个问题? 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
发表时间:2007-03-17
最近经常遇到 下面这个异常 ? 会不会是dao获取session有问题 |
|
返回顶楼 | |
发表时间:2007-03-17
不能进行跨session的lazy loading,把操作放在一个session里面就能解决。
|
|
返回顶楼 | |
发表时间:2007-03-17
其实问题在于你的两个操作是否是在一个事务里,通过查看spring的事务那部分代码可以得知,如果方法在事务中,那么方法中所有的session都是同一个,这个session和对应的transaction会组装成一个sessionHolder类然后放到当前线程中,如果不在一个事务中,那么每次调用dao都会得到一个新的session,这样两次得到同一个object会使这个object和两个session关联,具体的原因就是这样的,楼主不防对照着看一下,我觉得象楼主这个操作其实应该是放到同一个事务中的,在楼主的contraller不被包含在事务中,所以才会出现这个异常的吧,另,这个异常和1:N没有什么关系的,你可以查看一下spring的sessionfactoryutil类和hibernatetransactionmanager类就明白了,我可能讲的也不是很清楚
|
|
返回顶楼 | |
发表时间:2007-03-19
ahuaxuan 写道 其实问题在于你的两个操作是否是在一个事务里,通过查看spring的事务那部分代码可以得知,如果方法在事务中,那么方法中所有的session都是同一个,这个session和对应的transaction会组装成一个sessionHolder类然后放到当前线程中,如果不在一个事务中,那么每次调用dao都会得到一个新的session,这样两次得到同一个object会使这个object和两个session关联,具体的原因就是这样的,楼主不防对照着看一下,我觉得象楼主这个操作其实应该是放到同一个事务中的,在楼主的contraller不被包含在事务中,所以才会出现这个异常的吧,另,这个异常和1:N没有什么关系的,你可以查看一下spring的sessionfactoryutil类和hibernatetransactionmanager类就明白了,我可能讲的也不是很清楚
你讲得很清楚,我现在事务确实不是 定义在 controller层,而是 参考 appfuse <bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean"> <property name="dataSource" ref="dataSource"/> .... </bean> <bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager"> <property name="sessionFactory" ref="sessionFactory"/> </bean> <bean id="dao" class="org.appfuse.dao.hibernate.BaseDaoHibernate"> <property name="sessionFactory" ref="sessionFactory"/> </bean> <bean id="baseManager" class="org.appfuse.service.impl.BaseManagerImpl"> <property name="dao" ref="dao"/> </bean> 是 dao 在事务控制中。 至于 你说那个解决办法我还没试验,不过感觉你说的有道理。 这个问题我现在已经解决,我是这么做的 //添加或修改主题 forumTopic.setTitle(formBean.getTitle()); .... forumTopic.setBacks(null); //关键是加了这句话 forumManager.saveObject(forumTopic); //添加或修改回复 forumTopicBack.setContent(formBean.getContent()); .... forumManager.saveObject(forumTopicBack); 就是 1操作完毕后,把 1种的 collection 设成 null, 然后再 操作 n. 现在是成功了。 事务控制在 controller 层上 真的比 控制在 dao层好么? 希望继续讨论 |
|
返回顶楼 | |
发表时间:2007-03-19
引用 hibernate的session提供了一级缓存,每个session,对同一个id进行两次load,不会发送两条sql给数据库,但是session关闭的时候,一级缓存就失效了。
再参考 ahuaxuan 朋友 说的, 那再看上面的引用,是不是意味着 事务控制的范围越广,一级缓存利用率就越高 ? 效率就越大呢 ? 因为session只要不关闭,就能利用 hibernate 一级缓存。那让session关得越晚,就可能更多的用一级缓存。 迫切想 明确这个问题。 大家怎么看 : session,事务,一级缓存 三者关系 。 |
|
返回顶楼 | |
发表时间:2007-03-19
你可以看一下spring这块的源码,我觉得对hibernate的使用诠释的相当清晰。
只有在spring的实现中才是一个transaction范围内存在一个session,别把这个搞混了。 为了提高命中率也别在一级缓存的层面上作文章(建议二级缓存或者在应用层面上实现自己的缓存),如spring这样随开随关才是正途。 |
|
返回顶楼 | |
发表时间:2007-03-19
JavaFlasher 写道 引用 hibernate的session提供了一级缓存,每个session,对同一个id进行两次load,不会发送两条sql给数据库,但是session关闭的时候,一级缓存就失效了。
再参考 ahuaxuan 朋友 说的, 那再看上面的引用,是不是意味着 事务控制的范围越广,一级缓存利用率就越高 ? 效率就越大呢 ? 因为session只要不关闭,就能利用 hibernate 一级缓存。那让session关得越晚,就可能更多的用一级缓存。 迫切想 明确这个问题。 大家怎么看 : session,事务,一级缓存 三者关系 。 hibernate中,transaction来自session,一级缓存也在session中 引用 只有在spring的实现中才是一个transaction范围内存在一个session,别把这个搞混了。 其实不用spring也可以做到这一点,具体参考hibernate in action中的hibernateutil类,同spring一样,也是把这个session通过threadlocal放到thread中,只不过没有aop,就需要编程式事务了
|
|
返回顶楼 | |
发表时间:2007-03-19
ahuaxuan 写道 引用 只有在spring的实现中才是一个transaction范围内存在一个session,别把这个搞混了。 其实不用spring也可以做到这一点,具体参考hibernate in action中的hibernateutil类,同spring一样,也是把这个session通过threadlocal放到thread中,只不过没有aop,就需要编程式事务了我的意思是transaction和单个session没有必然联系,这只是spring的实现。 当然你自己也能这样实现。 |
|
返回顶楼 | |
发表时间:2007-03-19
没有人说transaction和单个session有联系,即使在spring里也是一样,两者还是没有必然联系,transaction真正的来源是数据源
|
|
返回顶楼 | |