Mixing typed with native queries in Spring Data JPA

Philipp Steinwender
1 min readMar 21, 2020

--

Hibernate caches entities for improved performance. After modifying queries the cache is updated. When using native queries within the same transaction, changes are not reflected in the cache. Mixing typed native queries, we need to manually tell hibernate to invalidate the cache manually. I had solved this issue for the first time recently. It took me some time to find a proper solution.

An example to describe my case:

List<Users> users = repository.find()doSomethingWith(users)
updateRating() => native query to recacalculate rating
List<Users> updatedUsers = repository.find() // no update receiveddoMoreWith(users)

In the second find() the updated rating was not available. Hibernate does not know what entities to evict from the cache because of the native query.

Detach

The best solution for this case I found was to detach the list of entities before loading again:

...
users.forEach(user -> entityManager.detach(user))
List<Users> updatedUsers = repository.find() // got update

Thanks to Thorben Janssen for writing the article about that!

Refresh

Searching for this issue, I found most often to refresh the entity. I would need to refresh each entity, resulting in lots of queries.

Clear

Another way would be to clear the entire cache.

// by annotation on top of Spring JPA Repository methods:
@Modifying(flushAutomatically = true, clearAutomatically = true)
// or manually via entityManager:
entityManager.flush()
entityManager.clear()

When clearing the cache, all entities are gone. The result were LazyInitializationExceptions. I would need to reload all entities in my transaction.

--

--

No responses yet