当前位置: 首页 > 面试题库 >

无关集合的休眠映射问题

尉迟正奇
2023-03-14
问题内容

欢迎,

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引用,从而引发“集合不与任何会话相关联”异常“。这解释了为什么在我的情况下,只有最后一个对象具有引用,而只有一个具有一切正常,以及您对延迟初始化问题的假设。

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



 类似资料:
  • 问题内容: 我需要预先将没有实现接口的枚举映射到现有数据库,该数据库使用将该枚举存储在与所有者类相同的表中。 在这种情况下应如何处理映射?持久化到数据库不会改变,因为实现该接口的所有枚举都将具有不同的值,但是我不确定应如何从数据库中检索对象(我是否需要自定义映射器,它将尝试实例化一个使用指定的enum类进行枚举吗?Hibernate是否本身支持此功能?)。 问题答案: 可以创建一个自定义(例如th

  • 问题内容: Hibernate提供的注释支持使用或两种类型的映射。当我们使用映射时,它使用的“名称” 而不是Enum 的表示形式。在数据库列仅包含一个字符的情况下,这是一个问题。例如,我有以下枚举: 当我坚持枚举使用,即休眠尝试在数据库中存储的值是开放的。但是,我的数据库列仅包含一个字符,因此会引发异常。 克服这个问题的一个办法是改变枚举类型持有单个字符(如,代替,)。但是,这降低了可读性。有什么

  • 问题内容: 我有一个颜色枚举 我有包含它的MyEntity。 我已经有一个UserType来映射我的枚举。 您知道如何在Hibernate hbm.xml中映射枚举集吗? 我需要一个UserType还是最简单的方法? 谢谢 编辑: 只是为了说明一下,我正在寻找 hbm.xml 配置而不是@CollectionOfElements注释 问题答案: 我使用EnumSet映射线程中的解决方案,该解决方案

  • 问题内容: 在具有两种类型的实体(父级和子级)的场景中: 父母-@OneToMany Collection孩子; 默认设置是对子级集合进行延迟加载。这种模式对少数儿童非常有效,但是如果这个数字很大,这似乎是不可持续的。因此,在某些情况下,我认为孩子的数量会很大,因此我使用了分页的服务方法(例如“ getChildren(父父母,int偏移量,int计数)”)。 问题是:这是处理此类情况的最佳方法吗

  • 问题内容: 我有一个hibernate映射的Java对象,其中充满了许多正常的可hibernate映射字段(例如字符串和整数)。 我向其中添加了一个新的嵌入式字段(该字段位于同一表中- 而不是映射),它是一个。我已经明确表示该字段可能实际上不包含任何内容(而不是每次访问它都必须进行处理)。 如何在文件中设置映射?我想hibernate来自动转换数据库到的,当它获取对象。它还应将的非空实例转换为的。

  • 问题内容: 在hibernate映射中,我设置了属性,这将获取父级的所有子级记录。 整个应用程序都在使用它。 这在我的应用程序的特定模块上造成了性能问题,我只想在其中获取父记录。 由于无法在其他许多地方使用该属性,因此我无法将其更改为。有没有办法来解决这个问题? 请让我知道是否需要更多信息。 问题答案: 这些在hibernate状态并不具有这种功能,因为它尊重您的习惯。因此,我建议解决您的需求的方