【问题标题】:JPA/Hibernate EntityGraph and CacheJPA/Hibernate EntityGraph 和缓存
【发布时间】:2017-09-29 21:45:32
【问题描述】:

使用 EntityGraphs 时 JPA 1 级缓存如何工作?

如果我打电话:

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

(顺便说一句,我在这里使用 Spring Data,这是我的自定义存储库中的一种方法,但这与问题无关)。

这将使用正确的 SELECT 语句访问数据库,包括系统和制造商表所需的所有连接。这工作正常,符合预期。

但是,如果我这样称呼:

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

第一个 findOne 调用将通过 SELECT 仅对 Tool 表访问数据库,这没问题,但第二个 findOne 不会访问数据库,而是从缓存中获取 Tool 实体。这是一个大问题,因为缓存的实体没有明显加载系统或制造商,如果我尝试访问它们,它们将被延迟加载,这是我试图通过 EntityGraph 避免的。

这应该发生吗?我期待第二次调用再次访问数据库,因为即使 Tool 实体已被缓存,EntityGraph 也指定从其他 2 个未缓存的表中获取实体。 如果 EntityGraph 将始终尝试从缓存中获取实体并且不考虑作为图表一部分的属性是否也在缓存中,那么对我来说这个功能基本上是无用的,因为它只会带来很多问题路。

【问题讨论】:

  • 我面临同样的问题。有什么发现吗?

标签: hibernate jpa


【解决方案1】:

在两条指令之间清除实体管理器似乎对我有用:

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

缺点是文档告诉#clear()

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

我尝试使用#detach(tool),但不起作用。

【讨论】:

  • 是的,清除整个持久性对我来说并不是解决方案,即使它解决了这个特定问题。我不确定这种行为是否是设计使然,但这使得整个实体图功能对我来说完全没用。
猜你喜欢
  • 1970-01-01
  • 2020-11-10
  • 2019-07-19
  • 2014-07-03
  • 1970-01-01
  • 2014-12-05
  • 2013-11-23
  • 2017-03-31
  • 2020-03-12
相关资源
最近更新 更多