Reputation: 323
How does the JPA Level 1 cache work when using EntityGraphs?
If I call:
Tool tool = toolRepository.findOne(id, CustomEntityGraph.fromAttributes(new String[] { "system", "manufacturer" }, EntityGraphType.LOAD));
(I'm using Spring Data here btw and this is a method from my custom repository, but that's not relevant for the question).
This will hit the database with the proper SELECT statement including all the needed JOINs to the System and Manufacturer tables. This is working perfectly fine and as expected.
However if I call this:
Tool tool = toolRepository.findOne(id);
Tool toolEg = toolRepository.findOne(id, CustomEntityGraph.fromAttributes(new String[] { "system", "manufacturer" }, EntityGraphType.LOAD));
The first findOne call will hit the database with a SELECT to the Tool table only which is ok, but the second findOne won't hit the database and will grab the Tool entity from the cache. This is a big issue because the cached entity doesn't have system or manufacturer loaded obviously and if I try to access them they will be lazily loaded which is what I was trying to avoid with the EntityGraph.
Is this supposed to happen? I was expecting the second call to hit the database again because even though the Tool entity is already cached the EntityGraph specifies fetching entities from 2 other tables that aren't cached. If the EntityGraph will always try to get entities from the cache and doesn't consider if the attributes that are part of the graph are also in the cache or not then to me this feature is basically useless as it will only bring lots of issues down the road.
Upvotes: 3
Views: 646
Reputation: 1885
Clearing the Entity Manager between both instructions seems to work for me:
Tool tool = toolRepository.findOne(id);
em.clear();
Tool toolEg = toolRepository.findOne(id, CustomEntityGraph.fromAttributes(new String[] { "system", "manufacturer" }, EntityGraphType.LOAD));
The downside is what the documentation tells about #clear()
:
Clear the persistence context, causing all managed entities to become detached. Changes made to entities that have not been flushed to the database will not be persisted.
I tried with #detach(tool)
but does not work.
Upvotes: 1