Skip to content

Commit

Permalink
Merge pull request #7348 from Sanne/2LCDisableOption
Browse files Browse the repository at this point in the history
Hibernate ORM configuration option to disable 2LC
  • Loading branch information
gsmet authored Feb 22, 2020
2 parents e281cf7 + a5d996e commit 905595f
Show file tree
Hide file tree
Showing 8 changed files with 92 additions and 44 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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.
* <p>
* Just cherry-pick which entities should be using the cache.
* <p>
* Set this to false to disable all 2nd level caches.
*/
@ConfigItem(defaultValue = "true")
public boolean secondLevelCachingEnabled;

public boolean isAnyPropertySet() {
return dialect.isPresent() ||
dialectStorageEngine.isPresent() ||
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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;
Expand Down Expand Up @@ -672,10 +678,24 @@ private void handleHibernateORMWithNoPersistenceXml(
}

// Caching
Map<String, String> cacheConfigEntries = HibernateConfigUtil
.getCacheConfigEntries(hibernateConfig);
for (Entry<String, String> 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<String, String> cacheConfigEntries = HibernateConfigUtil.getCacheConfigEntries(hibernateConfig);
for (Entry<String, String> 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);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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;
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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<String, Object> 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,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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);
}

Expand All @@ -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<Map.Entry<Object, Object>> entries = properties.entrySet();
for (Map.Entry<Object, Object> e : entries) {
final Object key = e.getKey();
if (!(key instanceof String)) {
log.infof("Ignoring persistence unit property key '%s' as it's not a String", key);
continue;
}
final Object value = e.getValue();
if (!(value instanceof String)) {
log.infof("Ignoring persistence unit property for key '%s' as the value is not a String", key);
continue;
}
clean.setProperty((String) key, (String) value);
}
return clean;
}

@Override
public URL getPersistenceUnitRootUrl() {
return null;
Expand Down
5 changes: 5 additions & 0 deletions integration-tests/jpa/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,11 @@
<artifactId>rest-assured</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-junit5-internal</artifactId>
<scope>test</scope>
</dependency>
</dependencies>

<build>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;

import org.hibernate.cache.spi.TimestampsCache;
import org.hibernate.internal.SessionImpl;

import io.quarkus.runtime.LaunchMode;
import io.quarkus.runtime.configuration.ProfileManager;

Expand Down Expand Up @@ -96,4 +99,14 @@ public String getCake() {
Cake c = (Cake) em.createQuery("from Cake").getSingleResult();
return c.getType();
}

@GET
@Produces(MediaType.TEXT_PLAIN)
@Path("/timestamps")
public String checkCachingState() {
SessionImpl sessionImpl = em.unwrap(SessionImpl.class);
TimestampsCache timestampsCache = sessionImpl.getSessionFactory().getCache().getTimestampsCache();
return timestampsCache.getClass().getName();
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package io.quarkus.it.jpa.configurationless;

import static org.hamcrest.core.StringContains.containsString;

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.RegisterExtension;

import io.quarkus.test.QuarkusUnitTest;
import io.restassured.RestAssured;

/**
* Similar to JPAConfigurationlessTest, yet explicitly disabling 2nd level caching,
* then asserting the TimestampsCacheDisabledImpl have been disabled as a consequence.
*/
public class JPACacheDisabled {

@RegisterExtension
static final QuarkusUnitTest config = new QuarkusUnitTest()
.withConfigurationResource("application.properties")
.overrideConfigKey("quarkus.hibernate-orm.second-level-caching-enabled", "false");

@Test
public void testInjection() {
RestAssured.when().get("/jpa-test").then()
.body(containsString("jpa=OK"));

RestAssured.when().get("/jpa-test/user-tx").then()
.body(containsString("jpa=OK"));

RestAssured.when().get("/jpa-test/timestamps").then()
.body(containsString("org.hibernate.cache.internal.TimestampsCacheDisabledImpl"));
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -20,5 +20,9 @@ public void testInjection() {

RestAssured.when().get("/jpa-test/user-tx").then()
.body(containsString("jpa=OK"));

RestAssured.when().get("/jpa-test/timestamps").then()
.body(containsString("org.hibernate.cache.internal.TimestampsCacheEnabledImpl"));
}

}

0 comments on commit 905595f

Please sign in to comment.