欢迎,
Hibernate映射存在一些问题。
数据库结构:
TableA -ID_A --PK TableB -ID_B --PK -ID_A -- FK -> TableA TableC -ID_C -- PK -ID_A -- FK -> TableA
POJO结构:
class TableA extends Pojo { /*Some Fields*/ } class TableB extends Pojo { TableA tableA; /*Some properties*/ } class TableC extends Pojo { TableA tableA; Collection<tableB> tableBs; }
我想拥有的是TableC Pojo映射中TableB元素的集合,映射键是tableA。
该集合应该是只读的。
映射应为hbm而非注释。
我可能已经以各种可能的方式完成了此操作…我遇到的关闭情况是,当我对一个TableC对象进行操作时,一切都是正确的,但是如果我加载它们的集合,则只有最后一个具有正确的集合集。
更新:案例描述。
用例1:加载TableC的单个对象
Session session = (Session) getHibernateTemplate().getSessionFactory().openSession(); SQLQuery sqlQuery = session.createSQLQuery("SELECT c.* FROM TableC c WHERE c.ID_C = 1"); //Oracle sqlQuery.addEntity("c", TableC.class); return sqlQuery.list(); //Return list with sigle object of TableC
在这种情况下,一切都可以正常工作。该对象将在TableB对象列表中加载所有数据和适当的项目。在这个对象上,我们可以操作,更改它并更新数据库中的修改。
用例2加载对象集合
Session session = (Session) getHibernateTemplate().getSessionFactory().openSession(); SQLQuery sqlQuery = session.createSQLQuery("SELECT c.* FROM TableC c WHERE c.ID_C in (1,2)"); //Oracle sqlQuery.addEntity("c", TableC.class); return sqlQuery.list(); // throws "collection is not associated with any session"
在这种情况下,Hibernate在检索下一个对象时引发异常。
*代码仅是示例,会话最终将关闭。
经过一些研究,问题出在Hibernate中,它被称为bug #HHH-2862
这基本上是由一个渴望的集合引起的,其中集合的键在结果中不是唯一的。
当Hibernate使用’persistenceContext.addUninitializedCollection()’初始化集合时,这将检测到已经添加了具有给定键的集合,然后将旧实例设置为null并将当前实例设置为该集合。但是,该集合已经通过较早的调用添加到了持久性上下文中,并且当StatefulPersistenceContext.initializeNonLazyCollections()在持久性上下文中迭代所有集合时,调用forceInitialization()引用时会击中null引用,从而引发“集合不与任何会话相关联”异常“。这解释了为什么在我的情况下,只有最后一个对象具有引用,而只有一个具有一切正常,以及您对延迟初始化问题的假设。
StatefulPersistenceContext.initializeNonLazyCollections()
forceInitialization()
一些想法如何绕过此错误?