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 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 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… |