`
chillwarmoon
  • 浏览: 153487 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

hibernate中对集合的共享参照问题

阅读更多

最近的开发一直在持久层周围,虽然做hibernate也有一段时间了,但是随着数据库表的增加,遇到了一些以前没有碰到过的问题。其中有一个问题就是对集合的共享参照问题(found shared references to a collection)具体是这样的:
数据库表的关系如下:



关系是这样的ALARMINFO表通过交叉表ALARMAUDIT和AUDITINFO建立多对多关系,ALARMINFO自身是一对多的关系,ALARMINFO表和ALARMCOMPRESS表是多对一的关系。
在这里抛开ALARMCOMPRESS表不讨论,对象之间的关系是双向关联,目标是这样的:生成一个新的ALARMINFO对象alarmInfo该对象子集合alarmInfos已经获得,将其赋值给该对象alarmInfo,该对象的auditInfos的赋值是这样的:将alarmInfos的其中一个元素对应的多个auditInfos赋值给auditInfos。

那这样的话最终save对象alarmInfo就会产生共享参照,即alarmInfo对auditInfos的参照,alarmInfo的子集合alarmInfos中的一个元素对auditInfos的参照。

有什么方法能够在加载alarmInfos的其中一个元素的auditInfos集合,并赋值给alarmInfo后,使得该集合再次恢复到未加载前的lazy状态呢,这样就可以避免对集合的共享参照问题。或者还有其他的方法。

java 代码
 
  1. public class AlarmInfo{  
  2. private Set alarmInfos;  
  3. private Set auditInfos;  
  4. private AlarmCompress alarmCompress;  
  5. }  
  6.   
  7. public class  AuditInfo{  
  8. private Set alarmInfos;  
  9. }  
  10.   
  11. public class AlarmCompress{  
  12. private Set alarmInfos;  
  13. }  
分享到:
评论
11 楼 chillwarmoon 2007-07-10  
xianyun 写道
另外在更新一个游离对象时,如果它有一个属性集合,该集合包含的session已经过期了,更新时也是可能会报错的。最好是在当前session下根据id取出对象,修改要更新的属性,这样来更新。这是另外一个问题了。


往往在做架构设计的时候,对于延长Session的考虑不是很完美,这就引起hibernate延迟加载在复杂的环境中的问题。我的这个问题通过普通的sql语句解决了,但是没有用hibernate的函数来解决。
10 楼 xianyun 2007-07-10  
另外在更新一个游离对象时,如果它有一个属性集合,该集合包含的session已经过期了,更新时也是可能会报错的。最好是在当前session下根据id取出对象,修改要更新的属性,这样来更新。这是另外一个问题了。
9 楼 xianyun 2007-07-10  
chillwarmoon 写道
抽取的是集合中的detached object,所以说还是引用的同样的对象。


不同集合中引用同一个对象是没有问题的。但是集合是不同的集合。

hibernate返回的集合不是普通的java.util中的集合,它包含了session和所属关联父对象的信息,你不能把它直接赋给另一个对象。
8 楼 chillwarmoon 2007-07-10  
抽取的是集合中的detached object,所以说还是引用的同样的对象。
7 楼 xianyun 2007-07-10  
<br/>
<strong>chillwarmoon 写道:</strong>
<div class='quote_div'>
<div class='quote_div'>
<div>你没有明白我的意思,我的意思是alarmInfo对auditInfos的引用,和alarmInfo的子对象集合的其中一个元素对auditInfos的引用,这两个引用是相同的,当保存alarmInfo的时候,然后出现问题。<br/>
<br/>
</div>
</div>
</div>
这两个集合怎么能是相同的呢?集合是不同的集合,但里面的元素可能是相同的。保存的时候,将子alarmInfo的auditInfos中的元素一个个取出来,加入到父alarmInfo的auditInfos集合中。
6 楼 chillwarmoon 2007-07-10  
<br/>
<strong>xianyun 写道:</strong><br/>
<div class='quote_div'>
<p> </p>
<div>“那这样的话最终save对象<font color='#ff0000'>alarmInfo</font>就会产生共享参照,即<font color='#ff0000'>alarmInfo</font>对auditInfos的参照,<font color='#ff0000'>alarmInfo</font>的子集合alarmInfos中的一个元素对auditInfos的参照。”<br/>
<br/>
按照你的说法,父alarmInfo和一个alarmInfo之间的关系 与 子alarmInfo和这个alarmInfo之间的关系是分别保存的,这会有什么矛盾吗?不过这种方法数据量会增加一些,并且维护关系麻烦一些。</div>
</div>
<br/>
<br/>
你没有明白我的意思,我的意思是alarmInfo对auditInfos的引用,和alarmInfo的子对象集合的其中一个元素对auditInfos的引用,这两个引用是相同的,当保存alarmInfo的时候,然后出现问题。<br/>
<br/>
5 楼 xianyun 2007-07-10  
<p> </p>
<div>“那这样的话最终save对象<font color='#ff0000'>alarmInfo</font>就会产生共享参照,即<font color='#ff0000'>alarmInfo</font>对auditInfos的参照,<font color='#ff0000'>alarmInfo</font>的子集合alarmInfos中的一个元素对auditInfos的参照。”<br/>
<br/>
按照你的说法,父alarmInfo和一个alarmInfo之间的关系 与 子alarmInfo和这个alarmInfo之间的关系是分别保存的,这会有什么矛盾吗?不过这种方法数据量会增加一些,并且维护关系麻烦一些。</div>
4 楼 chillwarmoon 2007-07-10  
zwchen 写道
你觉得这样领域建模是最优的吗,能否换成另外一种方式?

不敢说这一种是最优的,但是业务上的需求就是这样的。
3 楼 zwchen 2007-07-10  
你觉得这样领域建模是最优的吗,能否换成另外一种方式?OO很多时候不是目的。
小心Hibernate做这种复杂的集合映射时,用得不妥,会遇到严重的性能问题。
如果你愿意使用原生sql方式,也不失为一种解决方案。
我觉得,在企业应用里面,没有太大的必要去较真,如果你真的想通过纯技术方式去解决这个问题,hernate的source code也许是最好的文档。
2 楼 xianyun 2007-07-10  
问一句,什么叫“共享参照”,你这个是复杂了点,但是有什么问题吗?要维护关系就是把一个对象加入到一个集合中,并且该集合的映射的inverse是false的,不行吗?
1 楼 chillwarmoon 2007-07-09  
文本编辑器不支持这样的写法吗?发上去的表的结构打乱了,不过结合文字应该能够判断出来三个表之间的关系。

相关推荐

Global site tag (gtag.js) - Google Analytics