diff --git a/extensions/hibernate-orm/deployment/src/main/java/io/quarkus/hibernate/orm/deployment/HibernateOrmConfig.java b/extensions/hibernate-orm/deployment/src/main/java/io/quarkus/hibernate/orm/deployment/HibernateOrmConfig.java
index 1979c497e689e..d232028661602 100644
--- a/extensions/hibernate-orm/deployment/src/main/java/io/quarkus/hibernate/orm/deployment/HibernateOrmConfig.java
+++ b/extensions/hibernate-orm/deployment/src/main/java/io/quarkus/hibernate/orm/deployment/HibernateOrmConfig.java
@@ -148,6 +148,17 @@ public class HibernateOrmConfig {
@ConfigItem(name = "metrics.enabled", defaultValue = "false")
public boolean metricsEnabled;
+ /**
+ * The default in Quarkus is for 2nd level caching to be enabled,
+ * and a good implementation is already integrated for you.
+ *
+ * Just cherry-pick which entities should be using the cache.
+ *
+ * Set this to false to disable all 2nd level caches.
+ */
+ @ConfigItem(defaultValue = "true")
+ public boolean secondLevelCachingEnabled;
+
public boolean isAnyPropertySet() {
return dialect.isPresent() ||
dialectStorageEngine.isPresent() ||
diff --git a/extensions/hibernate-orm/deployment/src/main/java/io/quarkus/hibernate/orm/deployment/HibernateOrmProcessor.java b/extensions/hibernate-orm/deployment/src/main/java/io/quarkus/hibernate/orm/deployment/HibernateOrmProcessor.java
index 5dd0a319845f8..30664a2f20a50 100644
--- a/extensions/hibernate-orm/deployment/src/main/java/io/quarkus/hibernate/orm/deployment/HibernateOrmProcessor.java
+++ b/extensions/hibernate-orm/deployment/src/main/java/io/quarkus/hibernate/orm/deployment/HibernateOrmProcessor.java
@@ -2,6 +2,10 @@
import static io.quarkus.deployment.annotations.ExecutionTime.RUNTIME_INIT;
import static io.quarkus.deployment.annotations.ExecutionTime.STATIC_INIT;
+import static org.hibernate.cfg.AvailableSettings.JPA_SHARED_CACHE_MODE;
+import static org.hibernate.cfg.AvailableSettings.USE_DIRECT_REFERENCE_CACHE_ENTRIES;
+import static org.hibernate.cfg.AvailableSettings.USE_QUERY_CACHE;
+import static org.hibernate.cfg.AvailableSettings.USE_SECOND_LEVEL_CACHE;
import java.io.IOException;
import java.net.URL;
@@ -17,12 +21,14 @@
import java.util.Map;
import java.util.Map.Entry;
import java.util.Optional;
+import java.util.Properties;
import java.util.Set;
import java.util.stream.Collectors;
import javax.enterprise.inject.Produces;
import javax.persistence.PersistenceContext;
import javax.persistence.PersistenceUnit;
+import javax.persistence.SharedCacheMode;
import javax.persistence.spi.PersistenceUnitTransactionType;
import org.eclipse.microprofile.metrics.Metadata;
@@ -672,10 +678,24 @@ private void handleHibernateORMWithNoPersistenceXml(
}
// Caching
- Map cacheConfigEntries = HibernateConfigUtil
- .getCacheConfigEntries(hibernateConfig);
- for (Entry entry : cacheConfigEntries.entrySet()) {
- desc.getProperties().setProperty(entry.getKey(), entry.getValue());
+ if (hibernateConfig.secondLevelCachingEnabled) {
+ Properties p = desc.getProperties();
+ //Only set these if the user isn't making an explicit choice:
+ p.putIfAbsent(USE_DIRECT_REFERENCE_CACHE_ENTRIES, Boolean.TRUE);
+ p.putIfAbsent(USE_SECOND_LEVEL_CACHE, Boolean.TRUE);
+ p.putIfAbsent(USE_QUERY_CACHE, Boolean.TRUE);
+ p.putIfAbsent(JPA_SHARED_CACHE_MODE, SharedCacheMode.ENABLE_SELECTIVE);
+ Map cacheConfigEntries = HibernateConfigUtil.getCacheConfigEntries(hibernateConfig);
+ for (Entry entry : cacheConfigEntries.entrySet()) {
+ desc.getProperties().setProperty(entry.getKey(), entry.getValue());
+ }
+ } else {
+ //Unless the global switch is explicitly set to off, in which case we disable all caching:
+ Properties p = desc.getProperties();
+ p.put(USE_DIRECT_REFERENCE_CACHE_ENTRIES, Boolean.FALSE);
+ p.put(USE_SECOND_LEVEL_CACHE, Boolean.FALSE);
+ p.put(USE_QUERY_CACHE, Boolean.FALSE);
+ p.put(JPA_SHARED_CACHE_MODE, SharedCacheMode.NONE);
}
descriptors.add(desc);
diff --git a/extensions/hibernate-orm/runtime/src/main/java/io/quarkus/hibernate/orm/runtime/boot/FastBootMetadataBuilder.java b/extensions/hibernate-orm/runtime/src/main/java/io/quarkus/hibernate/orm/runtime/boot/FastBootMetadataBuilder.java
index ac6b49ef93855..db456e077dde3 100644
--- a/extensions/hibernate-orm/runtime/src/main/java/io/quarkus/hibernate/orm/runtime/boot/FastBootMetadataBuilder.java
+++ b/extensions/hibernate-orm/runtime/src/main/java/io/quarkus/hibernate/orm/runtime/boot/FastBootMetadataBuilder.java
@@ -7,15 +7,11 @@
import static org.hibernate.cfg.AvailableSettings.JPA_JDBC_PASSWORD;
import static org.hibernate.cfg.AvailableSettings.JPA_JDBC_URL;
import static org.hibernate.cfg.AvailableSettings.JPA_JDBC_USER;
-import static org.hibernate.cfg.AvailableSettings.JPA_SHARED_CACHE_MODE;
import static org.hibernate.cfg.AvailableSettings.JPA_TRANSACTION_TYPE;
import static org.hibernate.cfg.AvailableSettings.PASS;
import static org.hibernate.cfg.AvailableSettings.TRANSACTION_COORDINATOR_STRATEGY;
import static org.hibernate.cfg.AvailableSettings.URL;
import static org.hibernate.cfg.AvailableSettings.USER;
-import static org.hibernate.cfg.AvailableSettings.USE_DIRECT_REFERENCE_CACHE_ENTRIES;
-import static org.hibernate.cfg.AvailableSettings.USE_QUERY_CACHE;
-import static org.hibernate.cfg.AvailableSettings.USE_SECOND_LEVEL_CACHE;
import static org.hibernate.cfg.AvailableSettings.WRAP_RESULT_SETS;
import static org.hibernate.cfg.AvailableSettings.XML_MAPPING_ENABLED;
import static org.hibernate.internal.HEMLogging.messageLogger;
@@ -33,7 +29,6 @@
import java.util.concurrent.ConcurrentHashMap;
import javax.persistence.PersistenceException;
-import javax.persistence.SharedCacheMode;
import javax.persistence.spi.PersistenceUnitTransactionType;
import org.hibernate.boot.CacheRegionDefinition;
@@ -284,8 +279,6 @@ private MergedSettings mergeSettings(PersistenceUnitDescriptor persistenceUnit)
}
cfg.remove(JACC_ENABLED);
- enableCachingByDefault(cfg);
-
// here we are going to iterate the merged config settings looking for:
// 1) additional JACC permissions
// 2) additional cache region declarations
@@ -327,17 +320,6 @@ private MergedSettings mergeSettings(PersistenceUnitDescriptor persistenceUnit)
return mergedSettings;
}
- /**
- * Enable 2LC for entities and queries by default. Also allow "reference caching" by default.
- */
- private void enableCachingByDefault(final Map configurationValues) {
- //Only set these if the user isn't making an explicit choice:
- configurationValues.putIfAbsent(USE_DIRECT_REFERENCE_CACHE_ENTRIES, Boolean.TRUE);
- configurationValues.putIfAbsent(USE_SECOND_LEVEL_CACHE, Boolean.TRUE);
- configurationValues.putIfAbsent(USE_QUERY_CACHE, Boolean.TRUE);
- configurationValues.putIfAbsent(JPA_SHARED_CACHE_MODE, SharedCacheMode.ENABLE_SELECTIVE);
- }
-
public RecordedState build() {
MetadataImpl fullMeta = (MetadataImpl) MetadataBuildingProcess.complete(
managedResources,
diff --git a/extensions/hibernate-orm/runtime/src/main/java/io/quarkus/hibernate/orm/runtime/boot/LightPersistenceXmlDescriptor.java b/extensions/hibernate-orm/runtime/src/main/java/io/quarkus/hibernate/orm/runtime/boot/LightPersistenceXmlDescriptor.java
index 9893a01cd8ff3..d1e26398b6e14 100644
--- a/extensions/hibernate-orm/runtime/src/main/java/io/quarkus/hibernate/orm/runtime/boot/LightPersistenceXmlDescriptor.java
+++ b/extensions/hibernate-orm/runtime/src/main/java/io/quarkus/hibernate/orm/runtime/boot/LightPersistenceXmlDescriptor.java
@@ -3,9 +3,7 @@
import java.net.URL;
import java.util.Collections;
import java.util.List;
-import java.util.Map;
import java.util.Properties;
-import java.util.Set;
import javax.persistence.SharedCacheMode;
import javax.persistence.ValidationMode;
@@ -36,7 +34,7 @@ public LightPersistenceXmlDescriptor(final PersistenceUnitDescriptor toClone) {
this.validationMode = toClone.getValidationMode();
this.sharedCachemode = toClone.getSharedCacheMode();
this.managedClassNames = Collections.unmodifiableList(toClone.getManagedClassNames());
- this.properties = filterNonStrings(toClone.getProperties());
+ this.properties = toClone.getProperties();
verifyIgnoredFields(toClone);
}
@@ -63,25 +61,6 @@ private static void verifyIgnoredFields(final PersistenceUnitDescriptor toClone)
}
}
- private static final Properties filterNonStrings(final Properties properties) {
- Properties clean = new Properties();
- final Set> entries = properties.entrySet();
- for (Map.Entry