QueryKey not serializable when working with @TenantId
Description
When using @TenantId to perform multitenancy, org.hibernate.cache.spi.QueryKey instances becomes non-serializable, preventing query caching.
This is because of the Set<String> enabledFilterNames field, that is returned by org.hibernate.engine.spi.LoadQueryInfluencers#getEnabledFilterNames:
When enalbedFilters is empty, it returns Collections.emptySet(), which is serializable
But when multitenancy is enabled, the TenantIdBinder.FILTER_NAME filter is enabled, and getEnabledFilterNames return a Collections.unmodifiableSet( enabledFilters.keySet() ) => the keySet of the HashMap<String,Filter> enabledFilters is not serializable, hence the result of getEnabledFilterNames not being serializable
A copy of the filter keys should be performed to ensure serializability.
When using EHCache as the jsr107 impl, there's no exception thrown, but the query results are not cached (see my PR comment for details) => that's probably why the bug went unnoticed so far
With other JSR107 impls, like the RI or Caffeine, the problem is obvious (and blocking) because a serialization exception is thrown
Any chance this could be fixed in 6.2 ?
Alexis Hassler March 31, 2023 at 3:36 PM
I could reproduce the issue with Hibernate 6.2.0.Final, when enabling query cache and a filter. I’ve added a link to an example that reproduces the bug.
When using @TenantId to perform multitenancy, org.hibernate.cache.spi.QueryKey instances becomes non-serializable, preventing query caching.
This is because of the
Set<String> enabledFilterNames
field, that is returned byorg.hibernate.engine.spi.LoadQueryInfluencers#getEnabledFilterNames
:When
enalbedFilters
is empty, it returnsCollections.emptySet()
, which is serializableBut when multitenancy is enabled, the
TenantIdBinder.FILTER_NAME
filter is enabled, andgetEnabledFilterNames
return aCollections.unmodifiableSet( enabledFilters.keySet() )
=> the keySet of theHashMap<String,Filter> enabledFilters
is not serializable, hence the result ofgetEnabledFilterNames
not being serializableA copy of the filter keys should be performed to ensure serializability.