From c6300e4d54363329b510f19d15e4e2fb25b266e0 Mon Sep 17 00:00:00 2001 From: Debashish BHARALI Date: Wed, 20 Mar 2019 21:13:52 +0530 Subject: [PATCH 1/2] HHH-13331 - Query Cache should not be allowed for queris having Non Cacheable Query Spaces --- .../cache/spi/UpdateTimestampsCache.java | 9 ++- .../java/org/hibernate/loader/Loader.java | 57 ++++++++++++++++++- 2 files changed, 62 insertions(+), 4 deletions(-) diff --git a/hibernate-core/src/main/java/org/hibernate/cache/spi/UpdateTimestampsCache.java b/hibernate-core/src/main/java/org/hibernate/cache/spi/UpdateTimestampsCache.java index 8e9d293b9c60..01c7f4817650 100644 --- a/hibernate-core/src/main/java/org/hibernate/cache/spi/UpdateTimestampsCache.java +++ b/hibernate-core/src/main/java/org/hibernate/cache/spi/UpdateTimestampsCache.java @@ -13,7 +13,7 @@ import org.hibernate.engine.spi.SessionFactoryImplementor; import org.hibernate.engine.spi.SharedSessionContractImplementor; import org.hibernate.internal.CoreMessageLogger; - +import org.hibernate.loader.Loader; import org.jboss.logging.Logger; /** @@ -68,7 +68,9 @@ public void preInvalidate(Serializable[] spaces, SharedSessionContractImplemento if ( DEBUG_ENABLED ) { LOG.debugf( "Pre-invalidating space [%s], timestamp: %s", space, ts ); } - + if (!Loader.validateSpace(space)) { + continue; + } try { session.getEventListenerManager().cachePutStart(); @@ -104,6 +106,9 @@ public void invalidate(Serializable[] spaces, SharedSessionContractImplementor s if ( DEBUG_ENABLED ) { LOG.debugf( "Invalidating space [%s], timestamp: %s", space, ts ); } + if (!Loader.validateSpace(space)) { + continue; + } try { session.getEventListenerManager().cachePutStart(); diff --git a/hibernate-core/src/main/java/org/hibernate/loader/Loader.java b/hibernate-core/src/main/java/org/hibernate/loader/Loader.java index 4ef930929233..111a22106b25 100644 --- a/hibernate-core/src/main/java/org/hibernate/loader/Loader.java +++ b/hibernate-core/src/main/java/org/hibernate/loader/Loader.java @@ -20,8 +20,11 @@ import java.util.List; import java.util.Map; import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.TimeUnit; +import javax.persistence.Cacheable; + import org.hibernate.AssertionFailure; import org.hibernate.HibernateException; import org.hibernate.LockMode; @@ -31,6 +34,7 @@ import org.hibernate.Session; import org.hibernate.StaleObjectStateException; import org.hibernate.WrongClassException; +import org.hibernate.annotations.Cache; import org.hibernate.cache.spi.FilterKey; import org.hibernate.cache.spi.QueryCache; import org.hibernate.cache.spi.QueryKey; @@ -102,6 +106,10 @@ public abstract class Loader { protected static final CoreMessageLogger LOG = CoreLogging.messageLogger( Loader.class ); protected static final boolean DEBUG_ENABLED = LOG.isDebugEnabled(); + + private static Boolean metadataInitialized = false; + private static final Set cacheableSpacesSet = java.util.Collections + .newSetFromMap(new ConcurrentHashMap<>()); private final SessionFactoryImplementor factory; private volatile ColumnNameCache columnNameCache; @@ -2415,10 +2423,13 @@ protected List list( final QueryParameters queryParameters, final Set querySpaces, final Type[] resultTypes) throws HibernateException { + if (!metadataInitialized) { + initializeMetadata(); + } final boolean cacheable = factory.getSessionFactoryOptions().isQueryCacheEnabled() && queryParameters.isCacheable(); - - if ( cacheable ) { + + if ( cacheable && validateSpaces(querySpaces) ) { return listUsingQueryCache( session, queryParameters, querySpaces, resultTypes ); } else { @@ -2809,4 +2820,46 @@ protected String processDistinctKeyword( } return sql; } + + public static boolean validateSpaces(Set querySpaces) { + if(querySpaces==null || querySpaces.isEmpty()) { + return true; + } + for(Serializable space : querySpaces) { + if(!cacheableSpacesSet.contains(space)) { + return false; + } + } + return true; + } + + public static boolean validateSpace(Serializable space) { + return (space != null && cacheableSpacesSet.contains(space)) ? true : false; + } + + private synchronized void initializeMetadata() { + if (!metadataInitialized && factory != null && factory.getMetamodel() != null + && factory.getMetamodel().entityPersisters() != null + && factory.getMetamodel().collectionPersisters() != null) { + + Map entityPersisters = factory.getMetamodel().entityPersisters(); + for (Map.Entry entry : entityPersisters.entrySet()) { + if (entry.getValue().getCacheAccessStrategy() != null) { + for (Serializable space : entry.getValue().getQuerySpaces()) { + cacheableSpacesSet.add(space); + } + } + } + + Map collectionPersister = factory.getMetamodel().collectionPersisters(); + for (Map.Entry entry : collectionPersister.entrySet()) { + if (entry.getValue().getCacheAccessStrategy() != null) { + for (Serializable space : entry.getValue().getCollectionSpaces()) { + cacheableSpacesSet.add(space); + } + } + } + } + metadataInitialized = true; + } } From e948756026946d0b440efd2fa68befdccff8d21f Mon Sep 17 00:00:00 2001 From: Debashish BHARALI Date: Fri, 22 Mar 2019 13:17:18 +0530 Subject: [PATCH 2/2] HHH-13331 - Query Cache should not be allowed for queris having Non Cacheable Query Spaces - optimisation --- .../src/main/java/org/hibernate/loader/Loader.java | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/hibernate-core/src/main/java/org/hibernate/loader/Loader.java b/hibernate-core/src/main/java/org/hibernate/loader/Loader.java index 111a22106b25..29ff59350f74 100644 --- a/hibernate-core/src/main/java/org/hibernate/loader/Loader.java +++ b/hibernate-core/src/main/java/org/hibernate/loader/Loader.java @@ -20,11 +20,8 @@ import java.util.List; import java.util.Map; import java.util.Set; -import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.TimeUnit; -import javax.persistence.Cacheable; - import org.hibernate.AssertionFailure; import org.hibernate.HibernateException; import org.hibernate.LockMode; @@ -34,7 +31,6 @@ import org.hibernate.Session; import org.hibernate.StaleObjectStateException; import org.hibernate.WrongClassException; -import org.hibernate.annotations.Cache; import org.hibernate.cache.spi.FilterKey; import org.hibernate.cache.spi.QueryCache; import org.hibernate.cache.spi.QueryKey; @@ -108,8 +104,7 @@ public abstract class Loader { protected static final boolean DEBUG_ENABLED = LOG.isDebugEnabled(); private static Boolean metadataInitialized = false; - private static final Set cacheableSpacesSet = java.util.Collections - .newSetFromMap(new ConcurrentHashMap<>()); + private static final Set cacheableSpacesSet = new HashSet<>(); private final SessionFactoryImplementor factory; private volatile ColumnNameCache columnNameCache;