JPA/Hibernate实体图和缓存

3
JPA Level 1缓存在使用EntityGraphs时是如何工作的?
如果我调用:
Tool tool = toolRepository.findOne(id, CustomEntityGraph.fromAttributes(new String[] { "system", "manufacturer" }, EntityGraphType.LOAD));

顺便说一下,我在这里使用 Spring Data,并且这是我的自定义存储库中的一个方法,但这与问题无关。

这将使用适当的 SELECT 语句命中数据库,包括所有必需的 JOIN 到 System 和 Manufacturer 表。 这完全正常并且按预期运行。

然而,如果我调用这个:

Tool tool = toolRepository.findOne(id);
Tool toolEg = toolRepository.findOne(id, CustomEntityGraph.fromAttributes(new String[] { "system", "manufacturer" }, EntityGraphType.LOAD));

第一个findOne调用将仅命中Tool表的数据库,这是可以的,但第二个findOne不会命中数据库,并且将从缓存中获取Tool实体。这是一个大问题,因为缓存的实体显然没有加载系统或制造商,如果我尝试访问它们,它们将被懒加载,这正是我尝试使用EntityGraph避免的。
这是预期的吗?我希望第二个调用再次命中数据库,因为即使Tool实体已经被缓存,EntityGraph也指定了从其他2个未缓存表中获取实体。 如果EntityGraph总是尝试从缓存中获取实体,并且不考虑图形中的属性是否也在缓存中,那么对我来说,此功能基本上是无用的,因为它只会在以后带来很多问题。

我遇到了同样的问题。有什么发现吗? - Alfonso Nishikawa
1个回答

1
清除实体管理器在两个指令之间似乎对我有效:
Tool tool = toolRepository.findOne(id);
em.clear();
Tool toolEg = toolRepository.findOne(id, CustomEntityGraph.fromAttributes(new String[] { "system", "manufacturer" }, EntityGraphType.LOAD));

这个方法的缺点在于文档中对 #clear() 的描述:

清除持久化上下文,导致所有托管实体变为分离状态。对尚未刷新到数据库的实体所做的更改将不会被持久化。

我尝试使用 #detach(tool) 但没有成功。


是的,即使它解决了这个特定问题,清除整个持久性对我来说也不是一个解决方案。我不确定这种行为是否是设计上的问题,但这使得整个实体图功能对我完全无用。 - mfc

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接