When query caching is enabled on a query that contains multiple query parameters, subsequent queries with the exact same parameters run into cache misses. This seems to be caused because {{QueryKey.ParameterBindingsMementoImpl}} is constructed with a random order of parameter bindings in each different transaction. See {{generateQueryKeyMemento()}} method: [https://github.com/hibernate/hibernate-orm/blob/6.2.2/hibernate-core/src/main/java/org/hibernate/query/internal/QueryParameterBindingsImpl.java#L170-L194|https://github.com/hibernate/hibernate-orm/blob/6.2.2/hibernate-core/src/main/java/org/hibernate/query/internal/QueryParameterBindingsImpl.java#L170-L194|smart-link]
{{parameterBindingMap}} is a {{ConcurrentHashMap}} that will have an unpredictable order in each session. This method iterates over the values of this map and alters the {{hashCode}} of the cache key on each {{addToCacheKey()}} call. Different order of parameters result in {{ParameterBindingsMemento}} objects with different {{hashCode}} values even though they consist of exact identical parameters. This eventually results in a cache miss because the cache key object ({{QueryKey}}) equals method will return false when comparing the inner ParameterBindingsMemento objects that have different {{hashCode}}s: [https://github.com/hibernate/hibernate-orm/blob/6.2.2/hibernate-core/src/main/java/org/hibernate/cache/spi/QueryKey.java#L145-L147|https://github.com/hibernate/hibernate-orm/blob/6.2.2/hibernate-core/src/main/java/org/hibernate/cache/spi/QueryKey.java#L145-L147|smart-link]
The issue does not occur when query contains only 1 parameter because the order will be unchanged. If the query contains 2 parameters, then you have 50% chance for miss. If it has more parameters the possibility to miss increases exponentially. This is impacting the performance of the application quite severely because queries that have e.g. 7 parameters have 1/5040 (7 factorial) chance to do a cache hit the second time. So in practice, query cache is more or less not working at all for these queries.
Reproducer test case to be added , work in progress… . |
|