HHH-12549 Allow the behavior when a cache is missing to be configured by users
This commit is contained in:
parent
432adb36d8
commit
c52ff4d06c
|
@ -19,6 +19,16 @@ public interface ConfigSettings {
|
|||
*/
|
||||
String CACHE_MANAGER = PROP_PREFIX + "cache_manager";
|
||||
|
||||
/**
|
||||
* Define the behavior of the region factory when a cache is missing,
|
||||
* i.e. when the cache was not created by the cache manager as it started.
|
||||
*
|
||||
* See {@link MissingCacheStrategy} for the various possible values.
|
||||
*
|
||||
* Default value is {@link MissingCacheStrategy#FAIL}.
|
||||
*/
|
||||
String MISSING_CACHE_STRATEGY = PROP_PREFIX + "missing_cache_strategy";
|
||||
|
||||
/**
|
||||
* This is the legacy property name. No need to change it to fit under {@link #PROP_PREFIX}
|
||||
*/
|
||||
|
|
59
hibernate-ehcache/src/main/java/org/hibernate/cache/ehcache/MissingCacheStrategy.java
vendored
Normal file
59
hibernate-ehcache/src/main/java/org/hibernate/cache/ehcache/MissingCacheStrategy.java
vendored
Normal file
|
@ -0,0 +1,59 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
|
||||
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
|
||||
*/
|
||||
package org.hibernate.cache.ehcache;
|
||||
|
||||
import org.hibernate.internal.util.StringHelper;
|
||||
|
||||
public enum MissingCacheStrategy {
|
||||
|
||||
/**
|
||||
* Fail with an exception on missing caches.
|
||||
*/
|
||||
FAIL("fail"),
|
||||
|
||||
/**
|
||||
* Create a new cache when a cache is not found (see {@link #CREATE})
|
||||
* and also log a warning about the missing cache.
|
||||
*/
|
||||
CREATE_WARN("create-warn"),
|
||||
|
||||
/**
|
||||
* Create a new cache when a cache is not found,
|
||||
* without logging any warning about the missing cache.
|
||||
*
|
||||
* Note that caches created this way may be very badly configured (large size in particular)
|
||||
* unless an appropriate `<defaultCache>` entry is added to the Ehcache configuration.
|
||||
*/
|
||||
CREATE("create");
|
||||
|
||||
private final String externalRepresentation;
|
||||
|
||||
MissingCacheStrategy(String externalRepresentation) {
|
||||
this.externalRepresentation = externalRepresentation;
|
||||
}
|
||||
|
||||
public static MissingCacheStrategy interpretSetting(Object value) {
|
||||
if ( value instanceof MissingCacheStrategy ) {
|
||||
return (MissingCacheStrategy) value;
|
||||
}
|
||||
|
||||
final String externalRepresentation = value == null ? null : value.toString();
|
||||
|
||||
if ( StringHelper.isEmpty( externalRepresentation ) ) {
|
||||
// Use the default
|
||||
return MissingCacheStrategy.FAIL;
|
||||
}
|
||||
|
||||
for ( MissingCacheStrategy strategy : values() ) {
|
||||
if ( strategy.externalRepresentation.equals( externalRepresentation ) ) {
|
||||
return strategy;
|
||||
}
|
||||
}
|
||||
|
||||
throw new IllegalArgumentException( "Unrecognized missing cache strategy value : " + value );
|
||||
}
|
||||
}
|
|
@ -7,6 +7,8 @@
|
|||
package org.hibernate.cache.ehcache.internal;
|
||||
|
||||
|
||||
import org.hibernate.cache.ehcache.ConfigSettings;
|
||||
import org.hibernate.cache.ehcache.MissingCacheStrategy;
|
||||
import org.hibernate.internal.CoreMessageLogger;
|
||||
|
||||
import org.jboss.logging.Logger;
|
||||
|
@ -19,12 +21,12 @@ import static org.jboss.logging.Logger.Level.WARN;
|
|||
|
||||
/**
|
||||
* The jboss-logging {@link MessageLogger} for the hibernate-ehcache module. It reserves message ids ranging from
|
||||
* 20099 to 20099 (allow 20100 for our DeprecationLogger) inclusively.
|
||||
* 20001 to 20099 (allow 20100 for our DeprecationLogger) inclusively.
|
||||
* <p/>
|
||||
* New messages must be added after the last message defined to ensure message codes are unique.
|
||||
*/
|
||||
@MessageLogger(projectCode = "HHH")
|
||||
@ValidIdRange( min = 20001, max = 20099)
|
||||
@ValidIdRange(min = 20001, max = 20099)
|
||||
public interface EhCacheMessageLogger extends CoreMessageLogger {
|
||||
EhCacheMessageLogger INSTANCE = Logger.getMessageLogger(
|
||||
EhCacheMessageLogger.class,
|
||||
|
@ -111,4 +113,15 @@ public interface EhCacheMessageLogger extends CoreMessageLogger {
|
|||
)
|
||||
void softLockedCacheExpired(String regionName, Object key, String lock);
|
||||
|
||||
@LogMessage(level = WARN)
|
||||
@Message(
|
||||
value = "Missing cache[%s] was created on-the-fly." +
|
||||
" The created cache will use the <defaultCache> configuration: " +
|
||||
" make sure to configure it." +
|
||||
" You can disable this warning by setting '" + ConfigSettings.MISSING_CACHE_STRATEGY +
|
||||
"' to 'create'.",
|
||||
id = 20009
|
||||
)
|
||||
void missingCacheCreated(String regionName);
|
||||
|
||||
}
|
||||
|
|
|
@ -21,6 +21,7 @@ import org.hibernate.cache.CacheException;
|
|||
import org.hibernate.cache.cfg.spi.DomainDataRegionBuildingContext;
|
||||
import org.hibernate.cache.cfg.spi.DomainDataRegionConfig;
|
||||
import org.hibernate.cache.ehcache.ConfigSettings;
|
||||
import org.hibernate.cache.ehcache.MissingCacheStrategy;
|
||||
import org.hibernate.cache.internal.DefaultCacheKeysFactory;
|
||||
import org.hibernate.cache.spi.CacheKeysFactory;
|
||||
import org.hibernate.cache.spi.support.DomainDataStorageAccess;
|
||||
|
@ -39,11 +40,12 @@ import static org.hibernate.cache.ehcache.internal.HibernateEhcacheUtils.setCach
|
|||
* @author Alex Snaps
|
||||
*/
|
||||
public class EhcacheRegionFactory extends RegionFactoryTemplate {
|
||||
private static final Logger LOG = Logger.getLogger( EhcacheRegionFactory.class );
|
||||
private static final EhCacheMessageLogger LOG = EhCacheMessageLogger.INSTANCE;
|
||||
|
||||
private final CacheKeysFactory cacheKeysFactory;
|
||||
|
||||
private volatile CacheManager cacheManager;
|
||||
private volatile MissingCacheStrategy missingCacheStrategy;
|
||||
|
||||
public EhcacheRegionFactory() {
|
||||
this( DefaultCacheKeysFactory.INSTANCE );
|
||||
|
@ -103,11 +105,22 @@ public class EhcacheRegionFactory extends RegionFactoryTemplate {
|
|||
}
|
||||
|
||||
protected Cache createCache(String regionName) {
|
||||
throw new CacheException( "On-the-fly creation of Ehcache Cache objects is not supported [" + regionName + "]" );
|
||||
switch ( missingCacheStrategy ) {
|
||||
case CREATE_WARN:
|
||||
LOG.missingCacheCreated( regionName );
|
||||
cacheManager.addCache( regionName );
|
||||
return cacheManager.getCache( regionName );
|
||||
case CREATE:
|
||||
cacheManager.addCache( regionName );
|
||||
return cacheManager.getCache( regionName );
|
||||
case FAIL:
|
||||
throw new CacheException( "On-the-fly creation of Ehcache Cache objects is not supported [" + regionName + "]" );
|
||||
default:
|
||||
throw new IllegalStateException( "Unsupported missing cache strategy: " + missingCacheStrategy );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
// Lifecycle
|
||||
|
||||
|
@ -122,6 +135,9 @@ public class EhcacheRegionFactory extends RegionFactoryTemplate {
|
|||
if ( this.cacheManager == null ) {
|
||||
throw new CacheException( "Could not start Ehcache CacheManager" );
|
||||
}
|
||||
this.missingCacheStrategy = MissingCacheStrategy.interpretSetting(
|
||||
configValues.get( ConfigSettings.MISSING_CACHE_STRATEGY )
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -27,6 +27,16 @@ public interface ConfigSettings {
|
|||
*/
|
||||
String PROVIDER = PROP_PREFIX + "provider";
|
||||
|
||||
/**
|
||||
* Define the behavior of the region factory when a cache is missing,
|
||||
* i.e. when the cache was not created by the cache manager as it started.
|
||||
*
|
||||
* See {@link MissingCacheStrategy} for the various possible values.
|
||||
*
|
||||
* Default value is {@link MissingCacheStrategy#FAIL}.
|
||||
*/
|
||||
String MISSING_CACHE_STRATEGY = PROP_PREFIX + "missing_cache_strategy";
|
||||
|
||||
/**
|
||||
* Designates the URI for a specific JCache {@link CacheManager} JCacheRegionFactory
|
||||
* should ask the {@link javax.cache.spi.CachingProvider} for
|
||||
|
|
62
hibernate-jcache/src/main/java/org/hibernate/cache/jcache/MissingCacheStrategy.java
vendored
Normal file
62
hibernate-jcache/src/main/java/org/hibernate/cache/jcache/MissingCacheStrategy.java
vendored
Normal file
|
@ -0,0 +1,62 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
|
||||
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
|
||||
*/
|
||||
package org.hibernate.cache.jcache;
|
||||
|
||||
import org.hibernate.internal.util.StringHelper;
|
||||
|
||||
public enum MissingCacheStrategy {
|
||||
|
||||
/**
|
||||
* Fail with an exception on missing caches.
|
||||
*/
|
||||
FAIL("fail"),
|
||||
|
||||
/**
|
||||
* Create a new cache when a cache is not found (see {@link #CREATE}),
|
||||
* and also log a warning about the missing cache.
|
||||
*/
|
||||
CREATE_WARN("create-warn"),
|
||||
|
||||
/**
|
||||
* Create a new cache when a cache is not found,
|
||||
* without logging any warning about the missing cache.
|
||||
*
|
||||
* Note that caches created this way may be very badly configured (unlimited size and no eviction in particular)
|
||||
* unless the cache provider was explicitly configured to use an appropriate configuration for default caches.
|
||||
*
|
||||
* Ehcache in particular allows to set such default configuration using cache templates,
|
||||
* see http://www.ehcache.org/documentation/3.0/107.html#supplement-jsr-107-configurations
|
||||
*/
|
||||
CREATE("create");
|
||||
|
||||
private final String externalRepresentation;
|
||||
|
||||
MissingCacheStrategy(String externalRepresentation) {
|
||||
this.externalRepresentation = externalRepresentation;
|
||||
}
|
||||
|
||||
public static MissingCacheStrategy interpretSetting(Object value) {
|
||||
if ( value instanceof MissingCacheStrategy ) {
|
||||
return (MissingCacheStrategy) value;
|
||||
}
|
||||
|
||||
final String externalRepresentation = value == null ? null : value.toString();
|
||||
|
||||
if ( StringHelper.isEmpty( externalRepresentation ) ) {
|
||||
// Use the default
|
||||
return MissingCacheStrategy.FAIL;
|
||||
}
|
||||
|
||||
for ( MissingCacheStrategy strategy : values() ) {
|
||||
if ( strategy.externalRepresentation.equals( externalRepresentation ) ) {
|
||||
return strategy;
|
||||
}
|
||||
}
|
||||
|
||||
throw new IllegalArgumentException( "Unrecognized missing cache strategy value : " + value );
|
||||
}
|
||||
}
|
46
hibernate-jcache/src/main/java/org/hibernate/cache/jcache/internal/JCacheMessageLogger.java
vendored
Normal file
46
hibernate-jcache/src/main/java/org/hibernate/cache/jcache/internal/JCacheMessageLogger.java
vendored
Normal file
|
@ -0,0 +1,46 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
|
||||
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
|
||||
*/
|
||||
package org.hibernate.cache.jcache.internal;
|
||||
|
||||
|
||||
import org.hibernate.cache.jcache.ConfigSettings;
|
||||
import org.hibernate.internal.CoreMessageLogger;
|
||||
|
||||
import org.jboss.logging.Logger;
|
||||
import org.jboss.logging.annotations.LogMessage;
|
||||
import org.jboss.logging.annotations.Message;
|
||||
import org.jboss.logging.annotations.MessageLogger;
|
||||
import org.jboss.logging.annotations.ValidIdRange;
|
||||
|
||||
import static org.jboss.logging.Logger.Level.WARN;
|
||||
|
||||
/**
|
||||
* The jboss-logging {@link MessageLogger} for the hibernate-jcache module. It reserves message ids ranging from
|
||||
* 25099 to 25099 inclusively.
|
||||
* <p/>
|
||||
* New messages must be added after the last message defined to ensure message codes are unique.
|
||||
*/
|
||||
@MessageLogger(projectCode = "HHH")
|
||||
@ValidIdRange(min = 25001, max = 25099)
|
||||
public interface JCacheMessageLogger extends CoreMessageLogger {
|
||||
JCacheMessageLogger INSTANCE = Logger.getMessageLogger(
|
||||
JCacheMessageLogger.class,
|
||||
"org.hibernate.orm.javax.cache"
|
||||
);
|
||||
|
||||
@LogMessage(level = WARN)
|
||||
@Message(
|
||||
value = "Missing cache[%s] was created on-the-fly." +
|
||||
" The created cache will use a provider-specific default configuration:" +
|
||||
" make sure you defined one." +
|
||||
" You can disable this warning by setting '" + ConfigSettings.MISSING_CACHE_STRATEGY +
|
||||
"' to 'create'.",
|
||||
id = 25001
|
||||
)
|
||||
void missingCacheCreated(String regionName);
|
||||
|
||||
}
|
|
@ -12,6 +12,7 @@ import java.util.Map;
|
|||
import javax.cache.Cache;
|
||||
import javax.cache.CacheManager;
|
||||
import javax.cache.Caching;
|
||||
import javax.cache.configuration.MutableConfiguration;
|
||||
import javax.cache.spi.CachingProvider;
|
||||
|
||||
import org.hibernate.boot.registry.classloading.spi.ClassLoaderService;
|
||||
|
@ -21,6 +22,7 @@ import org.hibernate.cache.cfg.spi.DomainDataRegionBuildingContext;
|
|||
import org.hibernate.cache.cfg.spi.DomainDataRegionConfig;
|
||||
import org.hibernate.cache.internal.DefaultCacheKeysFactory;
|
||||
import org.hibernate.cache.jcache.ConfigSettings;
|
||||
import org.hibernate.cache.jcache.MissingCacheStrategy;
|
||||
import org.hibernate.cache.spi.CacheKeysFactory;
|
||||
import org.hibernate.cache.spi.support.DomainDataStorageAccess;
|
||||
import org.hibernate.cache.spi.support.RegionFactoryTemplate;
|
||||
|
@ -32,9 +34,12 @@ import org.hibernate.engine.spi.SessionFactoryImplementor;
|
|||
* @author Alex Snaps
|
||||
*/
|
||||
public class JCacheRegionFactory extends RegionFactoryTemplate {
|
||||
private static final JCacheMessageLogger LOG = JCacheMessageLogger.INSTANCE;
|
||||
|
||||
private final CacheKeysFactory cacheKeysFactory;
|
||||
|
||||
private volatile CacheManager cacheManager;
|
||||
private volatile MissingCacheStrategy missingCacheStrategy;
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
public JCacheRegionFactory() {
|
||||
|
@ -83,7 +88,17 @@ public class JCacheRegionFactory extends RegionFactoryTemplate {
|
|||
|
||||
@SuppressWarnings("WeakerAccess")
|
||||
protected Cache<Object, Object> createCache(String regionName) {
|
||||
throw new CacheException( "On-the-fly creation of JCache Cache objects is not supported [" + regionName + "]" );
|
||||
switch ( missingCacheStrategy ) {
|
||||
case CREATE_WARN:
|
||||
LOG.missingCacheCreated( regionName );
|
||||
return cacheManager.createCache( regionName, new MutableConfiguration<>() );
|
||||
case CREATE:
|
||||
return cacheManager.createCache( regionName, new MutableConfiguration<>() );
|
||||
case FAIL:
|
||||
throw new CacheException( "On-the-fly creation of JCache Cache objects is not supported [" + regionName + "]" );
|
||||
default:
|
||||
throw new IllegalStateException( "Unsupported missing cache strategy: " + missingCacheStrategy );
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -105,6 +120,7 @@ public class JCacheRegionFactory extends RegionFactoryTemplate {
|
|||
}
|
||||
|
||||
|
||||
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
// Lifecycle
|
||||
|
||||
|
@ -119,6 +135,9 @@ public class JCacheRegionFactory extends RegionFactoryTemplate {
|
|||
if ( this.cacheManager == null ) {
|
||||
throw new CacheException( "Could not locate/create CacheManager" );
|
||||
}
|
||||
this.missingCacheStrategy = MissingCacheStrategy.interpretSetting(
|
||||
getProp( configValues, ConfigSettings.MISSING_CACHE_STRATEGY )
|
||||
);
|
||||
}
|
||||
|
||||
@SuppressWarnings("WeakerAccess")
|
||||
|
|
Loading…
Reference in New Issue