小编典典

无关集合的休眠映射问题

hibernate

欢迎,

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在检索下一个对象时引发异常。

*代码仅是示例,会话最终将关闭。


阅读 313

收藏
2020-06-20

共1个答案

小编典典

经过一些研究,问题出在Hibernate中,它被称为bug
#HHH-2862

这基本上是由一个渴望的集合引起的,其中集合的键在结果中不是唯一的。

当Hibernate使用’persistenceContext.addUninitializedCollection()’初始化集合时,这将检测到已经添加了具有给定键的集合,然后将旧实例设置为null并将当前实例设置为该集合。但是,该集合已经通过较早的调用添加到了持久性上下文中,并且当StatefulPersistenceContext.initializeNonLazyCollections()在持久性上下文中迭代所有集合时,调用forceInitialization()引用时会击中null引用,从而引发“集合不与任何会话相关联”异常“。这解释了为什么在我的情况下,只有最后一个对象具有引用,而只有一个具有一切正常,以及您对延迟初始化问题的假设。

一些想法如何绕过此错误?

2020-06-20