我有一个位于内存中对象缓存后面的Hibernate数据访问层。对于客户端缓存未命中,内存缓存将调用Hibernate层以将对象图加载到缓存中。由于对象如何序列化到缓存中,我需要一次从Hibernate加载整个对象图(即没有延迟加载)。 Hibernate docs here中介绍了这样的场景。以下是摘录:
在具有单独业务层的应用程序中,业务逻辑必须在返回之前“准备”Web层所需的所有集合。这意味着业务层应该加载所有数据并将已初始化的所有数据返回到特定用例所需的表示/ Web层。通常,应用程序为Web层中需要的每个集合调用Hibernate.initialize()(此调用必须在会话关闭之前发生)或者使用带有FETCH子句或FetchMode.JOIN的Hibernate查询来急切地检索集合。在标准中。如果采用Command模式而不是Session Facade,这通常会更容易。
因为我不能直接在我的实体上启用Eager获取(我最终得到了this StackOverflow问题中记录的MultipleBagFetchException)我想我会保留默认的延迟加载行为,然后执行{{1}在对象中的每个集合上,以便完全饱和对象。问题是我的收藏品仍然是空的。
为了进一步混淆事情,这个策略似乎在我的单元测试中运行良好(我的对象已经正常饱和)但是当我将这个Hibernate层作为插件运行到我的内存缓存时(我提供了一个包含我的jar DAL,内存缓存将调用高速缓存未命中)我正在看到描述的行为。
目前我正在使用
处理我的会话Hibernate.initialize()
然后调用
<property name="current_session_context_class">thread</property>
在我的DAO中,之后我在会话中加载了要加载的对象。据我所知,我的会话处理对于我的工作单元测试和非工作DAO都是一样的。关于这里发生了什么的任何建议。如果您想了解更多信息,请告诉我们。
答案 0 :(得分:1)
我有时也会看到这种情况,并且很想知道答案。作为一种解决方法,我使用了两种不同的方法来初始化子项:
parent.getChildCollection().size()
Criteria
查询FetchMode.JOIN
醇>
那些似乎总能奏效。
答案 1 :(得分:1)
我找到了答案,但它并没有真正与错误的收集初始化有关,因为我的OP暗示但是我会在这里发布它,希望它可以帮助某人:
问题在于UUID(在整个服务层中作为字符串传递,因为这里无关紧要)我用来识别对象的是客户端以小写形式发送的,而我的(成功)单元测试是以大写形式发送UUID字符串。显然,数据库并不关心这种差异,并且能够至少返回图的根级对象,但是在给定根级对象的小写UUID标识符字符串的情况下,后续连接以使集合饱和失败。有谁知道为什么会这样?在我看来,Hibernate生成的SQL确实返回了正确的结果,无论UUID的情况如何,但Hibernate最终抛出了一些连接结果,因为UUID标识符在技术上并不匹配。