JPA / Hibernate EntityGraph和Cache

时间:2017-05-02 11:25:27

标签: hibernate jpa

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

如果我打电话:

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

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

这将使用适当的SELECT语句命中数据库,包括System和Manufacturer表所需的所有JOIN。这完全正常,正如预期的那样。

但是,如果我这样称呼:

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将始终尝试从缓存中获取实体,并且不考虑属于该图的属性是否也在缓存中,那么对我来说这个功能基本上没用,因为它只会带来很多问题这条路。

1 个答案:

答案 0 :(得分:0)

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

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

缺点是文档讲述的#clear()

  

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

我尝试使用#detach(tool),但无效。