Skip to content

Conversation

@debashishbharali
Copy link

HHH-13331 : Query Cache should not be allowed for queris having Non Cacheable Query Spaces

Analysis:

  • When query is cacheable i.e. 'org.hibernate.cacheable=true', and is having query spaces which are non cacheable, then this may lead to the well known 'N+1' issue.
  • I.e. the cached query result containing the 'N' ids, will further result in N queries of 'findById' to the database.

Expectation:

  • Query Cache should not be allowed for queries having Non Cacheable Query Spaces. Either throw an exception while loading the query, or rather ignore the query cache in this case.
  • With this, even high number of puts to 'UpdateTimestampCache' can be avoided. Which are originating from all the high number of transactional DMLs being executed to a query space which is non-cacheable.

Resolution : org.hibernate.loader.Loader.list() Mehod

  • Maintained a set of all the cacheable 'query space (String)' - called it 'cacheableSpacesSet' etc
  • Within the method 'Loader.list()', additional check of validating the current query's spaces from the initially maintained 'cacheableSpacesSet'
  • With the above additional validation, even though the system is configured as 'hibernate.cache.use_query_cache=true', and corresponding query is set as cacheable (i.e. 'org.hibernate.cacheable=true'), still the 'cacheable boolean' within the list() method will be set as false for query having query spaces which are not cacheable.

Performance:

  • This newly added additional validation uses 'HashSet.contains()' method internally. Which is having time complexity of O(1)
  • On a simple laptop, for individual call with one query space, it took an additional 24us to 40us for the complete additional logic.
  • On a server, this time is expected to reduce significantly.

@gbadner gbadner added the 5.2 label May 23, 2019
@beikov
Copy link
Member

beikov commented Sep 30, 2025

I'm going to close this PR because in ORM 6.0, we switched to caching the full query result. With ORM 6.5, we also added configurable query cache layouts per entity class, as well as a configurable global layout: https://github.com/hibernate/hibernate-orm/blob/6.5/release-announcement.adoc
With these features, the problem you're describing should go away by simply configuring the proper query cache layout.

@beikov beikov closed this Sep 30, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants