Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JPA/Hibernate EntityGraph and Cache

Tags:

hibernate

jpa

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.

like image 500
mfc Avatar asked Mar 02 '26 15:03

mfc


1 Answers

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.

like image 147
Alfonso Nishikawa Avatar answered Mar 05 '26 22:03

Alfonso Nishikawa



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!