HHH-11356 - Adjust the 2nd-Cache SPIs to better reflect supported uses
HHH-12323 - Update Statistics API and SPI based on changes to 2nd level caching changes HHH-12416 - set up relocation for hibernate-ehcache HHH-12417 - default strategy based on registrations with StrategySelector Basically reverted HHH-12416 and added basic support for Ehcache 2 again
This commit is contained in:
parent
84897f0ad0
commit
7f12e2a161
|
@ -145,6 +145,8 @@ public interface StrategySelector extends Service {
|
||||||
* Retrieve all of the registered implementors of the given strategy. Useful
|
* Retrieve all of the registered implementors of the given strategy. Useful
|
||||||
* to allow defaulting the choice to the single registered implementor when
|
* to allow defaulting the choice to the single registered implementor when
|
||||||
* only one is registered
|
* only one is registered
|
||||||
|
*
|
||||||
|
* @return The implementors. Should never return {@code null}
|
||||||
*/
|
*/
|
||||||
<T> Collection<Class<? extends T>> getRegisteredStrategyImplementors(Class<T> strategy);
|
<T> Collection<Class<? extends T>> getRegisteredStrategyImplementors(Class<T> strategy);
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,6 +12,7 @@ import java.util.Properties;
|
||||||
|
|
||||||
import org.hibernate.boot.registry.StandardServiceInitiator;
|
import org.hibernate.boot.registry.StandardServiceInitiator;
|
||||||
import org.hibernate.boot.registry.selector.spi.StrategySelector;
|
import org.hibernate.boot.registry.selector.spi.StrategySelector;
|
||||||
|
import org.hibernate.cache.CacheException;
|
||||||
import org.hibernate.cache.spi.RegionFactory;
|
import org.hibernate.cache.spi.RegionFactory;
|
||||||
import org.hibernate.cfg.AvailableSettings;
|
import org.hibernate.cfg.AvailableSettings;
|
||||||
import org.hibernate.internal.CoreLogging;
|
import org.hibernate.internal.CoreLogging;
|
||||||
|
@ -19,6 +20,9 @@ import org.hibernate.internal.CoreMessageLogger;
|
||||||
import org.hibernate.internal.util.config.ConfigurationHelper;
|
import org.hibernate.internal.util.config.ConfigurationHelper;
|
||||||
import org.hibernate.service.spi.ServiceRegistryImplementor;
|
import org.hibernate.service.spi.ServiceRegistryImplementor;
|
||||||
|
|
||||||
|
import static java.lang.Boolean.FALSE;
|
||||||
|
import static java.lang.Boolean.TRUE;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initiator for the {@link RegionFactory} service.
|
* Initiator for the {@link RegionFactory} service.
|
||||||
*
|
*
|
||||||
|
@ -39,58 +43,78 @@ public class RegionFactoryInitiator implements StandardServiceInitiator<RegionFa
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@SuppressWarnings({ "unchecked" })
|
|
||||||
public RegionFactory initiateService(Map configurationValues, ServiceRegistryImplementor registry) {
|
public RegionFactory initiateService(Map configurationValues, ServiceRegistryImplementor registry) {
|
||||||
final Properties p = new Properties();
|
final RegionFactory regionFactory = resolveRegionFactory( configurationValues, registry );
|
||||||
if (configurationValues != null) {
|
|
||||||
p.putAll( configurationValues );
|
|
||||||
}
|
|
||||||
|
|
||||||
final boolean useSecondLevelCache = ConfigurationHelper.getBoolean(
|
|
||||||
AvailableSettings.USE_SECOND_LEVEL_CACHE,
|
|
||||||
configurationValues,
|
|
||||||
true
|
|
||||||
);
|
|
||||||
final boolean useQueryCache = ConfigurationHelper.getBoolean(
|
|
||||||
AvailableSettings.USE_QUERY_CACHE,
|
|
||||||
configurationValues
|
|
||||||
);
|
|
||||||
|
|
||||||
RegionFactory regionFactory = NoCachingRegionFactory.INSTANCE;
|
|
||||||
|
|
||||||
// The cache provider is needed when we either have second-level cache enabled
|
|
||||||
// or query cache enabled. Note that useSecondLevelCache is enabled by default
|
|
||||||
if ( useSecondLevelCache || useQueryCache ) {
|
|
||||||
final Object setting = configurationValues != null
|
|
||||||
? configurationValues.get( AvailableSettings.CACHE_REGION_FACTORY )
|
|
||||||
: null;
|
|
||||||
regionFactory = registry.getService( StrategySelector.class ).resolveStrategy(
|
|
||||||
RegionFactory.class,
|
|
||||||
setting,
|
|
||||||
NoCachingRegionFactory.INSTANCE,
|
|
||||||
new StrategyCreatorRegionFactoryImpl( p )
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( regionFactory == NoCachingRegionFactory.INSTANCE ) {
|
|
||||||
// todo (5.3) : make this configurable?
|
|
||||||
boolean allowDefaulting = true;
|
|
||||||
if ( allowDefaulting ) {
|
|
||||||
final StrategySelector selector = registry.getService( StrategySelector.class );
|
|
||||||
final Collection<Class<? extends RegionFactory>> implementors = selector.getRegisteredStrategyImplementors( RegionFactory.class );
|
|
||||||
if ( implementors != null && implementors.size() == 1 ) {
|
|
||||||
regionFactory = selector.resolveStrategy( RegionFactory.class, implementors.iterator().next() );
|
|
||||||
configurationValues.put( AvailableSettings.CACHE_REGION_FACTORY, regionFactory );
|
|
||||||
configurationValues.put( AvailableSettings.USE_SECOND_LEVEL_CACHE, "true" );
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
LOG.debugf( "Cannot default RegionFactory based on registered strategies as `%s` RegionFactory strategies were registered" );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
LOG.debugf( "Cache region factory : %s", regionFactory.getClass().getName() );
|
LOG.debugf( "Cache region factory : %s", regionFactory.getClass().getName() );
|
||||||
|
|
||||||
return regionFactory;
|
return regionFactory;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@SuppressWarnings({"unchecked", "WeakerAccess"})
|
||||||
|
protected RegionFactory resolveRegionFactory(Map configurationValues, ServiceRegistryImplementor registry) {
|
||||||
|
final Properties p = new Properties();
|
||||||
|
p.putAll( configurationValues );
|
||||||
|
|
||||||
|
final Boolean useSecondLevelCache = ConfigurationHelper.getBooleanWrapper(
|
||||||
|
AvailableSettings.USE_SECOND_LEVEL_CACHE,
|
||||||
|
configurationValues,
|
||||||
|
null
|
||||||
|
);
|
||||||
|
final Boolean useQueryCache = ConfigurationHelper.getBooleanWrapper(
|
||||||
|
AvailableSettings.USE_QUERY_CACHE,
|
||||||
|
configurationValues,
|
||||||
|
null
|
||||||
|
);
|
||||||
|
|
||||||
|
// We should immediately return NoCachingRegionFactory if either:
|
||||||
|
// 1) both are explicitly FALSE
|
||||||
|
// 2) USE_SECOND_LEVEL_CACHE is FALSE and USE_QUERY_CACHE is null
|
||||||
|
if ( useSecondLevelCache != null && useSecondLevelCache == FALSE ) {
|
||||||
|
if ( useQueryCache == null || useQueryCache == FALSE ) {
|
||||||
|
return NoCachingRegionFactory.INSTANCE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
final Object setting = configurationValues.get( AvailableSettings.CACHE_REGION_FACTORY );
|
||||||
|
|
||||||
|
final StrategySelector selector = registry.getService( StrategySelector.class );
|
||||||
|
final Collection<Class<? extends RegionFactory>> implementors = selector.getRegisteredStrategyImplementors( RegionFactory.class );
|
||||||
|
|
||||||
|
if ( ( useSecondLevelCache != null && useSecondLevelCache == TRUE )
|
||||||
|
|| ( useQueryCache != null && useQueryCache == TRUE ) ) {
|
||||||
|
// if either are explicitly defined and one is TRUE, we need a RegionFactory
|
||||||
|
if ( setting == null && implementors.size() != 1 ) {
|
||||||
|
throw new CacheException( "Caching was explicitly requested, but no RegionFactory was defined and there is not a single registered RegionFactory" );
|
||||||
|
}
|
||||||
|
final RegionFactory regionFactory = registry.getService( StrategySelector.class ).resolveStrategy(
|
||||||
|
RegionFactory.class,
|
||||||
|
setting,
|
||||||
|
(RegionFactory) null,
|
||||||
|
new StrategyCreatorRegionFactoryImpl( p )
|
||||||
|
);
|
||||||
|
|
||||||
|
if ( regionFactory != null ) {
|
||||||
|
return regionFactory;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if ( implementors.size() == 1 ) {
|
||||||
|
final RegionFactory regionFactory = selector.resolveStrategy( RegionFactory.class, implementors.iterator().next() );
|
||||||
|
configurationValues.put( AvailableSettings.CACHE_REGION_FACTORY, regionFactory );
|
||||||
|
configurationValues.put( AvailableSettings.USE_SECOND_LEVEL_CACHE, "true" );
|
||||||
|
|
||||||
|
return regionFactory;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
LOG.debugf(
|
||||||
|
"Cannot default RegionFactory based on registered strategies as `%s` RegionFactory strategies were registered",
|
||||||
|
implementors
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return NoCachingRegionFactory.INSTANCE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,6 +15,7 @@ import org.jboss.logging.annotations.Message;
|
||||||
import org.jboss.logging.annotations.MessageLogger;
|
import org.jboss.logging.annotations.MessageLogger;
|
||||||
import org.jboss.logging.annotations.ValidIdRange;
|
import org.jboss.logging.annotations.ValidIdRange;
|
||||||
|
|
||||||
|
import static org.jboss.logging.Logger.Level.INFO;
|
||||||
import static org.jboss.logging.Logger.Level.WARN;
|
import static org.jboss.logging.Logger.Level.WARN;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -28,18 +29,47 @@ public interface SecondLevelCacheLogger extends BasicLogger {
|
||||||
"org.hibernate.orm.cache"
|
"org.hibernate.orm.cache"
|
||||||
);
|
);
|
||||||
|
|
||||||
|
int NAMESPACE = 90001000;
|
||||||
|
|
||||||
|
@LogMessage(level = WARN)
|
||||||
|
@Message(
|
||||||
|
value = "Attempt to restart an already started RegionFactory. Use sessionFactory.close() between " +
|
||||||
|
"repeated calls to buildSessionFactory. Using previously created RegionFactory.",
|
||||||
|
id = NAMESPACE + 1
|
||||||
|
)
|
||||||
|
void attemptToStartAlreadyStartedCacheProvider();
|
||||||
|
|
||||||
|
@LogMessage(level = WARN)
|
||||||
|
@Message(
|
||||||
|
value = "Attempt to restop an already stopped JCacheRegionFactory.",
|
||||||
|
id = NAMESPACE + 2
|
||||||
|
)
|
||||||
|
void attemptToStopAlreadyStoppedCacheProvider();
|
||||||
|
|
||||||
@LogMessage( level = WARN )
|
@LogMessage( level = WARN )
|
||||||
@Message(
|
@Message(
|
||||||
value = "Read-only caching was requested for mutable entity [%s]",
|
value = "Read-only caching was requested for mutable entity [%s]",
|
||||||
id = 90001001
|
id = NAMESPACE + 3
|
||||||
)
|
)
|
||||||
void readOnlyCachingMutableEntity(NavigableRole navigableRole);
|
void readOnlyCachingMutableEntity(NavigableRole navigableRole);
|
||||||
|
|
||||||
@LogMessage( level = WARN )
|
@LogMessage( level = WARN )
|
||||||
@Message(
|
@Message(
|
||||||
value = "Read-only caching was requested for mutable natural-id for entity [%s]",
|
value = "Read-only caching was requested for mutable natural-id for entity [%s]",
|
||||||
id = 90001002
|
id = NAMESPACE + 4
|
||||||
)
|
)
|
||||||
void readOnlyCachingMutableNaturalId(NavigableRole navigableRole);
|
void readOnlyCachingMutableNaturalId(NavigableRole navigableRole);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Log a message (WARN) about expiry of soft-locked region.
|
||||||
|
*/
|
||||||
|
@LogMessage(level = INFO)
|
||||||
|
@Message(
|
||||||
|
value = "Cache[%s] Key[%s]\n" +
|
||||||
|
"A soft-locked cache entry was expired by the underlying cache. If this happens regularly you " +
|
||||||
|
"should consider increasing the cache timeouts and/or capacity limits",
|
||||||
|
id = NAMESPACE + 5
|
||||||
|
)
|
||||||
|
void softLockedCacheExpired(String regionName, Object key);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,6 +15,7 @@ import java.util.concurrent.locks.Lock;
|
||||||
import java.util.concurrent.locks.ReentrantReadWriteLock;
|
import java.util.concurrent.locks.ReentrantReadWriteLock;
|
||||||
|
|
||||||
import org.hibernate.cache.spi.DomainDataRegion;
|
import org.hibernate.cache.spi.DomainDataRegion;
|
||||||
|
import org.hibernate.cache.spi.SecondLevelCacheLogger;
|
||||||
import org.hibernate.cache.spi.access.SoftLock;
|
import org.hibernate.cache.spi.access.SoftLock;
|
||||||
import org.hibernate.engine.spi.SharedSessionContractImplementor;
|
import org.hibernate.engine.spi.SharedSessionContractImplementor;
|
||||||
|
|
||||||
|
@ -179,6 +180,7 @@ public abstract class AbstractReadWriteAccess extends AbstractCachedDomainDataAc
|
||||||
|
|
||||||
@SuppressWarnings("WeakerAccess")
|
@SuppressWarnings("WeakerAccess")
|
||||||
protected void handleLockExpiry(SharedSessionContractImplementor session, Object key, Lockable lock) {
|
protected void handleLockExpiry(SharedSessionContractImplementor session, Object key, Lockable lock) {
|
||||||
|
SecondLevelCacheLogger.INSTANCE.softLockedCacheExpired( getRegion().getName(), key );
|
||||||
log.info( "Cached entry expired : " + key );
|
log.info( "Cached entry expired : " + key );
|
||||||
|
|
||||||
// create new lock that times out immediately
|
// create new lock that times out immediately
|
||||||
|
|
|
@ -8,17 +8,18 @@ package org.hibernate.test.cache;
|
||||||
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
|
||||||
|
import org.hibernate.boot.registry.BootstrapServiceRegistry;
|
||||||
import org.hibernate.boot.registry.BootstrapServiceRegistryBuilder;
|
import org.hibernate.boot.registry.BootstrapServiceRegistryBuilder;
|
||||||
|
import org.hibernate.boot.registry.StandardServiceRegistry;
|
||||||
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
|
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
|
||||||
import org.hibernate.boot.registry.selector.spi.StrategySelector;
|
import org.hibernate.boot.registry.selector.spi.StrategySelector;
|
||||||
import org.hibernate.cache.internal.EnabledCaching;
|
import org.hibernate.cache.internal.NoCachingRegionFactory;
|
||||||
import org.hibernate.cache.spi.RegionFactory;
|
import org.hibernate.cache.spi.RegionFactory;
|
||||||
import org.hibernate.cfg.AvailableSettings;
|
import org.hibernate.cfg.AvailableSettings;
|
||||||
import org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl;
|
import org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl;
|
||||||
import org.hibernate.engine.jdbc.connections.spi.ConnectionProvider;
|
import org.hibernate.engine.jdbc.connections.spi.ConnectionProvider;
|
||||||
|
|
||||||
import org.hibernate.testing.cache.CachingRegionFactory;
|
import org.hibernate.testing.junit4.BaseUnitTestCase;
|
||||||
import org.hibernate.testing.junit4.BaseNonConfigCoreFunctionalTestCase;
|
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
import static org.hamcrest.CoreMatchers.equalTo;
|
import static org.hamcrest.CoreMatchers.equalTo;
|
||||||
|
@ -28,48 +29,78 @@ import static org.hamcrest.MatcherAssert.assertThat;
|
||||||
/**
|
/**
|
||||||
* @author Steve Ebersole
|
* @author Steve Ebersole
|
||||||
*/
|
*/
|
||||||
public class SingleRegisteredProviderTest extends BaseNonConfigCoreFunctionalTestCase {
|
public class SingleRegisteredProviderTest extends BaseUnitTestCase {
|
||||||
@Override
|
@Test
|
||||||
protected void configureStandardServiceRegistryBuilder(StandardServiceRegistryBuilder ssrb) {
|
public void testCachingExplicitlyDisabled() {
|
||||||
super.configureStandardServiceRegistryBuilder( ssrb );
|
final StandardServiceRegistry registry = new StandardServiceRegistryBuilder()
|
||||||
|
.applySetting( AvailableSettings.USE_SECOND_LEVEL_CACHE, "false" )
|
||||||
|
.build();
|
||||||
|
|
||||||
ssrb.applySetting( AvailableSettings.USE_SECOND_LEVEL_CACHE, "false" );
|
assertThat( registry.getService( RegionFactory.class ), instanceOf( NoCachingRegionFactory.class ) );
|
||||||
ssrb.applySetting( AvailableSettings.CACHE_REGION_PREFIX, "" );
|
|
||||||
ssrb.applySetting( AvailableSettings.CACHE_REGION_FACTORY, "" );
|
|
||||||
|
|
||||||
ssrb.applySetting( AvailableSettings.CONNECTION_PROVIDER, "" );
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void configureBootstrapServiceRegistryBuilder(BootstrapServiceRegistryBuilder bsrb) {
|
|
||||||
super.configureBootstrapServiceRegistryBuilder( bsrb );
|
|
||||||
bsrb.applyStrategySelector( ConnectionProvider.class, "testing", DriverManagerConnectionProviderImpl.class );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testCachingExpectations() {
|
public void testCachingImplicitlyEnabledRegistered() {
|
||||||
final Collection<Class<? extends RegionFactory>> implementors = sessionFactory().getServiceRegistry()
|
final BootstrapServiceRegistry bsr = new BootstrapServiceRegistryBuilder()
|
||||||
|
.build();
|
||||||
|
|
||||||
|
final Collection<Class<? extends RegionFactory>> implementors = bsr
|
||||||
.getService( StrategySelector.class )
|
.getService( StrategySelector.class )
|
||||||
.getRegisteredStrategyImplementors( RegionFactory.class );
|
.getRegisteredStrategyImplementors( RegionFactory.class );
|
||||||
|
|
||||||
assertThat( implementors.size(), equalTo( 1 ) );
|
assertThat( implementors.size(), equalTo( 1 ) );
|
||||||
assertThat( sessionFactory().getSessionFactoryOptions().isSecondLevelCacheEnabled(), equalTo( true ) );
|
|
||||||
assertThat( sessionFactory().getCache(), instanceOf( EnabledCaching.class ) );
|
final StandardServiceRegistry ssr = new StandardServiceRegistryBuilder( bsr )
|
||||||
assertThat( sessionFactory().getCache().getRegionFactory(), instanceOf( CachingRegionFactory.class ) );
|
.applySetting( AvailableSettings.USE_SECOND_LEVEL_CACHE, "" )
|
||||||
assertThat( implementors.iterator().next(), equalTo( CachingRegionFactory.class ) );
|
.build();
|
||||||
|
|
||||||
|
assertThat( ssr.getService( RegionFactory.class ), instanceOf( NoCachingRegionFactory.class ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testConnectionsExpectations() {
|
public void testCachingImplicitlyEnabledNoRegistered() {
|
||||||
final Collection<Class<? extends ConnectionProvider>> implementors = sessionFactory().getServiceRegistry()
|
final BootstrapServiceRegistry bsr = new BootstrapServiceRegistryBuilder()
|
||||||
|
.build();
|
||||||
|
|
||||||
|
final Collection<Class<? extends RegionFactory>> implementors = bsr
|
||||||
.getService( StrategySelector.class )
|
.getService( StrategySelector.class )
|
||||||
.getRegisteredStrategyImplementors( ConnectionProvider.class );
|
.getRegisteredStrategyImplementors( RegionFactory.class );
|
||||||
|
|
||||||
assertThat( implementors.size(), equalTo( 1 ) );
|
assertThat( implementors.size(), equalTo( 1 ) );
|
||||||
|
|
||||||
final ConnectionProvider configuredProvider = sessionFactory().getServiceRegistry().getService( ConnectionProvider.class );
|
bsr.getService( StrategySelector.class ).unRegisterStrategyImplementor(
|
||||||
|
RegionFactory.class,
|
||||||
|
implementors.iterator().next()
|
||||||
|
);
|
||||||
|
|
||||||
|
final StandardServiceRegistry ssr = new StandardServiceRegistryBuilder( bsr )
|
||||||
|
.applySetting( AvailableSettings.USE_SECOND_LEVEL_CACHE, "" )
|
||||||
|
.build();
|
||||||
|
|
||||||
|
assertThat( ssr.getService( RegionFactory.class ), instanceOf( NoCachingRegionFactory.class ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testConnectionsRegistered() {
|
||||||
|
final BootstrapServiceRegistry bsr = new BootstrapServiceRegistryBuilder()
|
||||||
|
.build();
|
||||||
|
|
||||||
|
final Collection<Class<? extends ConnectionProvider>> implementors = bsr
|
||||||
|
.getService( StrategySelector.class )
|
||||||
|
.getRegisteredStrategyImplementors( ConnectionProvider.class );
|
||||||
|
|
||||||
|
assertThat( implementors.size(), equalTo( 0 ) );
|
||||||
|
|
||||||
|
bsr.getService( StrategySelector.class ).registerStrategyImplementor(
|
||||||
|
ConnectionProvider.class,
|
||||||
|
"testing",
|
||||||
|
DriverManagerConnectionProviderImpl.class
|
||||||
|
);
|
||||||
|
|
||||||
|
final StandardServiceRegistry ssr = new StandardServiceRegistryBuilder( bsr ).build();
|
||||||
|
|
||||||
|
final ConnectionProvider configuredProvider = ssr.getService( ConnectionProvider.class );
|
||||||
|
|
||||||
assertThat( configuredProvider, instanceOf( DriverManagerConnectionProviderImpl.class ) );
|
assertThat( configuredProvider, instanceOf( DriverManagerConnectionProviderImpl.class ) );
|
||||||
assertThat( implementors.iterator().next(), equalTo( DriverManagerConnectionProviderImpl.class ) );
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,31 +5,11 @@
|
||||||
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
apply from: rootProject.file( 'gradle/base-information.gradle' )
|
apply from: rootProject.file( 'gradle/published-java-module.gradle' )
|
||||||
apply from: rootProject.file( 'gradle/publishing-repos.gradle' )
|
|
||||||
apply from: rootProject.file( 'gradle/publishing-pom.gradle' )
|
|
||||||
apply plugin: 'maven-publish'
|
|
||||||
apply plugin: 'maven-publish-auth'
|
|
||||||
|
|
||||||
description = "(deprecated - use `org.hibernate:hibernate-jcache:${project.version}` + `org.ehcache:ehcache:3.0.0` instead)"
|
description = "Integration for using Ehcache 2.x as a Hibernate second-level-cache provider"
|
||||||
|
|
||||||
ext {
|
dependencies {
|
||||||
relocatedGroupId = 'org.hibernate'
|
compile project( ':hibernate-core' )
|
||||||
relocatedArtifactId = 'hibernate-jcache'
|
compile( libraries.ehcache )
|
||||||
relocatedVersion = project.version
|
|
||||||
}
|
}
|
||||||
|
|
||||||
publishing {
|
|
||||||
publications {
|
|
||||||
publishedArtifacts {
|
|
||||||
pom.withXml {
|
|
||||||
def relocation = asNode().appendNode( 'distributionManagement' ).appendNode( 'relocation' )
|
|
||||||
relocation.appendNode( 'groupId', project.relocatedGroupId)
|
|
||||||
relocation.appendNode( 'artifactId', project.relocatedArtifactId )
|
|
||||||
relocation.appendNode( 'version', project.relocatedVersion )
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
task release( dependsOn: bintrayUpload )
|
|
28
hibernate-ehcache/src/main/java/org/hibernate/cache/ehcache/ConfigSettings.java
vendored
Normal file
28
hibernate-ehcache/src/main/java/org/hibernate/cache/ehcache/ConfigSettings.java
vendored
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
/*
|
||||||
|
* 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 net.sf.ehcache.CacheManager;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Steve Ebersole
|
||||||
|
*/
|
||||||
|
public interface ConfigSettings {
|
||||||
|
String SIMPLE_FACTORY_NAME = "jcache";
|
||||||
|
|
||||||
|
String PROP_PREFIX = "hibernate.cache.ehcache.";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Allows providing `hibernate-jcache` with a custom JCache {@link CacheManager}.
|
||||||
|
*/
|
||||||
|
String CACHE_MANAGER = PROP_PREFIX + "cache_manager";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This is the legacy property name. No need to change it to fit under {@link #PROP_PREFIX}
|
||||||
|
*/
|
||||||
|
String EHCACHE_CONFIGURATION_RESOURCE_NAME = "net.sf.ehcache.configurationResourceName";
|
||||||
|
}
|
48
hibernate-ehcache/src/main/java/org/hibernate/cache/ehcache/internal/DomainDataRegionImpl.java
vendored
Normal file
48
hibernate-ehcache/src/main/java/org/hibernate/cache/ehcache/internal/DomainDataRegionImpl.java
vendored
Normal file
|
@ -0,0 +1,48 @@
|
||||||
|
/*
|
||||||
|
* 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.internal;
|
||||||
|
|
||||||
|
import net.sf.ehcache.Cache;
|
||||||
|
|
||||||
|
import org.hibernate.cache.cfg.spi.DomainDataRegionBuildingContext;
|
||||||
|
import org.hibernate.cache.cfg.spi.DomainDataRegionConfig;
|
||||||
|
import org.hibernate.cache.spi.CacheKeysFactory;
|
||||||
|
import org.hibernate.cache.spi.RegionFactory;
|
||||||
|
import org.hibernate.cache.spi.support.DomainDataRegionTemplate;
|
||||||
|
|
||||||
|
import org.jboss.logging.Logger;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Steve Ebersole
|
||||||
|
*/
|
||||||
|
public class DomainDataRegionImpl extends DomainDataRegionTemplate {
|
||||||
|
private static final Logger log = Logger.getLogger( DomainDataRegionImpl.class );
|
||||||
|
|
||||||
|
@SuppressWarnings("WeakerAccess")
|
||||||
|
public DomainDataRegionImpl(
|
||||||
|
DomainDataRegionConfig regionConfig,
|
||||||
|
RegionFactory regionFactory,
|
||||||
|
Cache underlyingCache,
|
||||||
|
CacheKeysFactory cacheKeysFactory,
|
||||||
|
DomainDataRegionBuildingContext buildingContext) {
|
||||||
|
super(
|
||||||
|
regionConfig,
|
||||||
|
regionFactory,
|
||||||
|
new DomainDataStorageAccessImpl( underlyingCache ),
|
||||||
|
cacheKeysFactory,
|
||||||
|
buildingContext
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Public override for testing use only
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public DomainDataStorageAccessImpl getCacheStorageAccess() {
|
||||||
|
return (DomainDataStorageAccessImpl) super.getCacheStorageAccess();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,25 @@
|
||||||
|
/*
|
||||||
|
* 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.internal;
|
||||||
|
|
||||||
|
import net.sf.ehcache.Cache;
|
||||||
|
|
||||||
|
import org.hibernate.cache.spi.support.DomainDataStorageAccess;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Steve Ebersole
|
||||||
|
*/
|
||||||
|
public class DomainDataStorageAccessImpl extends StorageAccessImpl implements DomainDataStorageAccess {
|
||||||
|
public DomainDataStorageAccessImpl(Cache underlyingCache) {
|
||||||
|
super( underlyingCache );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void putFromLoad(Object key, Object value) {
|
||||||
|
putIntoCache( key, value );
|
||||||
|
}
|
||||||
|
}
|
112
hibernate-ehcache/src/main/java/org/hibernate/cache/ehcache/internal/EhCacheMessageLogger.java
vendored
Normal file
112
hibernate-ehcache/src/main/java/org/hibernate/cache/ehcache/internal/EhCacheMessageLogger.java
vendored
Normal file
|
@ -0,0 +1,112 @@
|
||||||
|
/*
|
||||||
|
* 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.internal;
|
||||||
|
|
||||||
|
|
||||||
|
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 static org.jboss.logging.Logger.Level.WARN;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The jboss-logging {@link MessageLogger} for the hibernate-ehcache module. It reserves message ids ranging from
|
||||||
|
* 20001 to 25000 inclusively.
|
||||||
|
* <p/>
|
||||||
|
* New messages must be added after the last message defined to ensure message codes are unique.
|
||||||
|
*/
|
||||||
|
@MessageLogger(projectCode = "HHH")
|
||||||
|
public interface EhCacheMessageLogger extends CoreMessageLogger {
|
||||||
|
EhCacheMessageLogger INSTANCE = Logger.getMessageLogger(
|
||||||
|
EhCacheMessageLogger.class,
|
||||||
|
"org.hibernate.orm.cache.ehcache"
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Log a message (WARN) about inability to find configuration file
|
||||||
|
*
|
||||||
|
* @param name The name of the configuration file
|
||||||
|
*/
|
||||||
|
@LogMessage(level = WARN)
|
||||||
|
@Message(value = "Could not find configuration [%s]; using defaults.", id = 20002)
|
||||||
|
void unableToFindConfiguration(String name);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Log a message (WARN) about inability to find named cache configuration
|
||||||
|
*
|
||||||
|
* @param name The name of the cache configuration
|
||||||
|
*/
|
||||||
|
@LogMessage(level = WARN)
|
||||||
|
@Message(value = "Could not find a specific ehcache configuration for cache named [%s]; using defaults.", id = 20003)
|
||||||
|
void unableToFindEhCacheConfiguration(String name);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Logs a message about not being able to resolve the configuration by resource name.
|
||||||
|
*
|
||||||
|
* @param configurationResourceName The resource name we attempted to resolve
|
||||||
|
*/
|
||||||
|
@LogMessage(level = WARN)
|
||||||
|
@Message(
|
||||||
|
value = "A configurationResourceName was set to %s but the resource could not be loaded from the classpath. " +
|
||||||
|
"Ehcache will configure itself using defaults.",
|
||||||
|
id = 20004
|
||||||
|
)
|
||||||
|
void unableToLoadConfiguration(String configurationResourceName);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Logs a message (WARN) about attempt to use an incompatible
|
||||||
|
* {@link net.sf.ehcache.config.TerracottaConfiguration.ValueMode}.
|
||||||
|
*/
|
||||||
|
@LogMessage(level = WARN)
|
||||||
|
@Message(
|
||||||
|
value = "The default cache value mode for this Ehcache configuration is \"identity\". " +
|
||||||
|
"This is incompatible with clustered Hibernate caching - the value mode has therefore been " +
|
||||||
|
"switched to \"serialization\"",
|
||||||
|
id = 20005
|
||||||
|
)
|
||||||
|
void incompatibleCacheValueMode();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Logs a message (WARN) about attempt to use an incompatible
|
||||||
|
* {@link net.sf.ehcache.config.TerracottaConfiguration.ValueMode}.
|
||||||
|
*
|
||||||
|
* @param cacheName The name of the cache whose config attempted to specify value mode.
|
||||||
|
*/
|
||||||
|
@LogMessage(level = WARN)
|
||||||
|
@Message(value = "The value mode for the cache[%s] is \"identity\". This is incompatible with clustered Hibernate caching - "
|
||||||
|
+ "the value mode has therefore been switched to \"serialization\"", id = 20006)
|
||||||
|
void incompatibleCacheValueModePerCache(String cacheName);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Log a message (WARN) about an attempt to specify read-only caching for a mutable entity
|
||||||
|
*
|
||||||
|
* @param entityName The name of the entity
|
||||||
|
*/
|
||||||
|
@LogMessage(level = WARN)
|
||||||
|
@Message(value = "read-only cache configured for mutable entity [%s]", id = 20007)
|
||||||
|
void readOnlyCacheConfiguredForMutableEntity(String entityName);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Log a message (WARN) about expiry of soft-locked region.
|
||||||
|
*
|
||||||
|
* @param regionName The region name
|
||||||
|
* @param key The cache key
|
||||||
|
* @param lock The lock
|
||||||
|
*/
|
||||||
|
@LogMessage(level = WARN)
|
||||||
|
@Message(
|
||||||
|
value = "Cache[%s] Key[%s] Lockable[%s]\n" +
|
||||||
|
"A soft-locked cache entry was expired by the underlying Ehcache. If this happens regularly you " +
|
||||||
|
"should consider increasing the cache timeouts and/or capacity limits",
|
||||||
|
id = 20008
|
||||||
|
)
|
||||||
|
void softLockedCacheExpired(String regionName, Object key, String lock);
|
||||||
|
|
||||||
|
}
|
322
hibernate-ehcache/src/main/java/org/hibernate/cache/ehcache/internal/EhcacheRegionFactory.java
vendored
Normal file
322
hibernate-ehcache/src/main/java/org/hibernate/cache/ehcache/internal/EhcacheRegionFactory.java
vendored
Normal file
|
@ -0,0 +1,322 @@
|
||||||
|
/*
|
||||||
|
* 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.internal;
|
||||||
|
|
||||||
|
import java.net.MalformedURLException;
|
||||||
|
import java.net.URL;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
|
|
||||||
|
import net.sf.ehcache.Cache;
|
||||||
|
import net.sf.ehcache.CacheManager;
|
||||||
|
import net.sf.ehcache.config.Configuration;
|
||||||
|
import net.sf.ehcache.config.ConfigurationFactory;
|
||||||
|
|
||||||
|
import org.hibernate.boot.registry.classloading.spi.ClassLoaderService;
|
||||||
|
import org.hibernate.boot.spi.SessionFactoryOptions;
|
||||||
|
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.internal.DefaultCacheKeysFactory;
|
||||||
|
import org.hibernate.cache.spi.CacheKeysFactory;
|
||||||
|
import org.hibernate.cache.spi.DomainDataRegion;
|
||||||
|
import org.hibernate.cache.spi.QueryResultsRegion;
|
||||||
|
import org.hibernate.cache.spi.RegionFactory;
|
||||||
|
import org.hibernate.cache.spi.SecondLevelCacheLogger;
|
||||||
|
import org.hibernate.cache.spi.TimestampsRegion;
|
||||||
|
import org.hibernate.cache.spi.access.AccessType;
|
||||||
|
import org.hibernate.cache.spi.support.RegionNameQualifier;
|
||||||
|
import org.hibernate.cache.spi.support.SimpleTimestamper;
|
||||||
|
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||||
|
|
||||||
|
import org.jboss.logging.Logger;
|
||||||
|
|
||||||
|
import static org.hibernate.cache.ehcache.ConfigSettings.EHCACHE_CONFIGURATION_RESOURCE_NAME;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Steve Ebersole
|
||||||
|
* @author Alex Snaps
|
||||||
|
*/
|
||||||
|
public class EhcacheRegionFactory implements RegionFactory {
|
||||||
|
private static final Logger LOG = Logger.getLogger( EhcacheRegionFactory.class );
|
||||||
|
|
||||||
|
private final AtomicBoolean started = new AtomicBoolean( false );
|
||||||
|
private final CacheKeysFactory cacheKeysFactory;
|
||||||
|
|
||||||
|
private volatile CacheManager cacheManager;
|
||||||
|
private SessionFactoryOptions options;
|
||||||
|
|
||||||
|
public EhcacheRegionFactory() {
|
||||||
|
this( DefaultCacheKeysFactory.INSTANCE );
|
||||||
|
}
|
||||||
|
|
||||||
|
public EhcacheRegionFactory(CacheKeysFactory cacheKeysFactory) {
|
||||||
|
this.cacheKeysFactory = cacheKeysFactory;
|
||||||
|
}
|
||||||
|
|
||||||
|
public CacheManager getCacheManager() {
|
||||||
|
return cacheManager;
|
||||||
|
}
|
||||||
|
|
||||||
|
public SessionFactoryOptions getOptions() {
|
||||||
|
return options;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isMinimalPutsEnabledByDefault() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public AccessType getDefaultAccessType() {
|
||||||
|
return AccessType.READ_WRITE;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long nextTimestamp() {
|
||||||
|
return SimpleTimestamper.next();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long getTimeout() {
|
||||||
|
return SimpleTimestamper.timeOut();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void start(SessionFactoryOptions settings, Map configValues) throws CacheException {
|
||||||
|
if ( started.compareAndSet( false, true ) ) {
|
||||||
|
synchronized ( this ) {
|
||||||
|
this.options = settings;
|
||||||
|
try {
|
||||||
|
this.cacheManager = getCacheManager( settings, configValues );
|
||||||
|
}
|
||||||
|
finally {
|
||||||
|
if ( this.cacheManager == null ) {
|
||||||
|
started.set( false );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
SecondLevelCacheLogger.INSTANCE.attemptToStartAlreadyStartedCacheProvider();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private CacheManager getCacheManager(SessionFactoryOptions settings, Map properties) {
|
||||||
|
final Object explicitCacheManager = properties.get( ConfigSettings.CACHE_MANAGER );
|
||||||
|
if ( explicitCacheManager != null ) {
|
||||||
|
return useExplicitCacheManager( settings, explicitCacheManager );
|
||||||
|
}
|
||||||
|
|
||||||
|
return useNormalCacheManager( settings, properties );
|
||||||
|
}
|
||||||
|
|
||||||
|
protected CacheManager resolveCacheManager(SessionFactoryOptions settings, Map properties) {
|
||||||
|
return useNormalCacheManager( settings, properties );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Locate the CacheManager during start-up. protected to allow for subclassing
|
||||||
|
* such as SingletonEhcacheRegionFactory
|
||||||
|
*/
|
||||||
|
protected static CacheManager useNormalCacheManager(SessionFactoryOptions settings, Map properties) {
|
||||||
|
try {
|
||||||
|
String configurationResourceName = null;
|
||||||
|
if ( properties != null ) {
|
||||||
|
configurationResourceName = (String) properties.get( EHCACHE_CONFIGURATION_RESOURCE_NAME );
|
||||||
|
}
|
||||||
|
if ( configurationResourceName == null || configurationResourceName.length() == 0 ) {
|
||||||
|
final Configuration configuration = ConfigurationFactory.parseConfiguration();
|
||||||
|
return new CacheManager( configuration );
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
final URL url = loadResource( configurationResourceName, settings );
|
||||||
|
final Configuration configuration = HibernateEhcacheUtils.loadAndCorrectConfiguration( url );
|
||||||
|
return new CacheManager( configuration );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (net.sf.ehcache.CacheException e) {
|
||||||
|
if ( e.getMessage().startsWith(
|
||||||
|
"Cannot parseConfiguration CacheManager. Attempt to create a new instance of " +
|
||||||
|
"CacheManager using the diskStorePath"
|
||||||
|
) ) {
|
||||||
|
throw new CacheException(
|
||||||
|
"Attempt to restart an already started EhCacheRegionFactory. " +
|
||||||
|
"Use sessionFactory.close() between repeated calls to buildSessionFactory. " +
|
||||||
|
"Consider using SingletonEhCacheRegionFactory. Error from ehcache was: " + e.getMessage()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
throw new CacheException( e );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static URL loadResource(String configurationResourceName, SessionFactoryOptions settings) {
|
||||||
|
URL url = settings.getServiceRegistry()
|
||||||
|
.getService( ClassLoaderService.class )
|
||||||
|
.locateResource( configurationResourceName );
|
||||||
|
|
||||||
|
if ( url == null ) {
|
||||||
|
final ClassLoader standardClassloader = Thread.currentThread().getContextClassLoader();
|
||||||
|
if ( standardClassloader != null ) {
|
||||||
|
url = standardClassloader.getResource( configurationResourceName );
|
||||||
|
}
|
||||||
|
if ( url == null ) {
|
||||||
|
url = EhcacheRegionFactory.class.getResource( configurationResourceName );
|
||||||
|
}
|
||||||
|
if ( url == null ) {
|
||||||
|
try {
|
||||||
|
url = new URL( configurationResourceName );
|
||||||
|
}
|
||||||
|
catch ( MalformedURLException e ) {
|
||||||
|
// ignore
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ( LOG.isDebugEnabled() ) {
|
||||||
|
LOG.debugf(
|
||||||
|
"Creating EhCacheRegionFactory from a specified resource: %s. Resolved to URL: %s",
|
||||||
|
configurationResourceName,
|
||||||
|
url
|
||||||
|
);
|
||||||
|
}
|
||||||
|
if ( url == null ) {
|
||||||
|
EhCacheMessageLogger.INSTANCE.unableToLoadConfiguration( configurationResourceName );
|
||||||
|
}
|
||||||
|
|
||||||
|
return url;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Load a resource from the classpath.
|
||||||
|
*/
|
||||||
|
protected URL loadResource(String configurationResourceName) {
|
||||||
|
if ( ! isStarted() ) {
|
||||||
|
throw new IllegalStateException( "Cannot load resource through a non-started EhcacheRegionFactory" );
|
||||||
|
}
|
||||||
|
|
||||||
|
return loadResource( configurationResourceName, options );
|
||||||
|
}
|
||||||
|
|
||||||
|
private CacheManager useExplicitCacheManager(SessionFactoryOptions settings, Object setting) {
|
||||||
|
if ( setting instanceof CacheManager ) {
|
||||||
|
return (CacheManager) setting;
|
||||||
|
}
|
||||||
|
|
||||||
|
final Class<? extends CacheManager> cacheManagerClass;
|
||||||
|
if ( setting instanceof Class ) {
|
||||||
|
cacheManagerClass = (Class<? extends CacheManager>) setting;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
cacheManagerClass = settings.getServiceRegistry().getService( ClassLoaderService.class )
|
||||||
|
.classForName( setting.toString() );
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
return cacheManagerClass.newInstance();
|
||||||
|
}
|
||||||
|
catch (InstantiationException | IllegalAccessException e) {
|
||||||
|
throw new CacheException( "Could not use explicit CacheManager : " + setting );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void stop() {
|
||||||
|
if ( started.compareAndSet( true, false ) ) {
|
||||||
|
synchronized ( this ) {
|
||||||
|
releaseCacheManager();
|
||||||
|
cacheManager = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
SecondLevelCacheLogger.INSTANCE.attemptToStopAlreadyStoppedCacheProvider();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void releaseCacheManager() {
|
||||||
|
// todo (5.3) : if this is a manager instance that was provided to us we should probably not close it...
|
||||||
|
// - when the explicit `setting` passed to `#useExplicitCacheManager` is
|
||||||
|
// a CacheManager instance
|
||||||
|
cacheManager.shutdown();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String qualify(String regionName) {
|
||||||
|
return RegionNameQualifier.INSTANCE.qualify( regionName, options );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public QueryResultsRegion buildQueryResultsRegion(
|
||||||
|
String regionName,
|
||||||
|
SessionFactoryImplementor sessionFactory) {
|
||||||
|
return new QueryResultsRegionImpl(
|
||||||
|
regionName,
|
||||||
|
this,
|
||||||
|
getOrCreateCache( regionName, sessionFactory )
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public TimestampsRegion buildTimestampsRegion(
|
||||||
|
String regionName,
|
||||||
|
SessionFactoryImplementor sessionFactory) {
|
||||||
|
return new TimestampsRegionImpl(
|
||||||
|
regionName,
|
||||||
|
this,
|
||||||
|
getOrCreateCache( regionName, sessionFactory )
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public DomainDataRegion buildDomainDataRegion(
|
||||||
|
DomainDataRegionConfig regionConfig,
|
||||||
|
DomainDataRegionBuildingContext buildingContext) {
|
||||||
|
return new DomainDataRegionImpl(
|
||||||
|
regionConfig,
|
||||||
|
this,
|
||||||
|
getOrCreateCache( regionConfig.getRegionName(), buildingContext.getSessionFactory() ),
|
||||||
|
cacheKeysFactory,
|
||||||
|
buildingContext
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected Cache getOrCreateCache(String unqualifiedRegionName, SessionFactoryImplementor sessionFactory) {
|
||||||
|
checkStatus();
|
||||||
|
assert !RegionNameQualifier.INSTANCE.isQualified( unqualifiedRegionName, sessionFactory.getSessionFactoryOptions() );
|
||||||
|
|
||||||
|
final String qualifiedRegionName = RegionNameQualifier.INSTANCE.qualify(
|
||||||
|
unqualifiedRegionName,
|
||||||
|
sessionFactory.getSessionFactoryOptions()
|
||||||
|
);
|
||||||
|
|
||||||
|
final Cache cache = cacheManager.getCache( qualifiedRegionName );
|
||||||
|
if ( cache == null ) {
|
||||||
|
return createCache( qualifiedRegionName );
|
||||||
|
}
|
||||||
|
return cache;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected Cache createCache(String regionName) {
|
||||||
|
throw new CacheException( "On-the-fly creation of JCache Cache objects is not supported [" + regionName + "]" );
|
||||||
|
}
|
||||||
|
|
||||||
|
protected String getProp(Map properties, String prop) {
|
||||||
|
return properties != null ? (String) properties.get( prop ) : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void checkStatus() {
|
||||||
|
if ( ! isStarted() ) {
|
||||||
|
throw new IllegalStateException( "JCacheRegionFactory not yet started!" );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean isStarted() {
|
||||||
|
return started.get() && cacheManager != null;
|
||||||
|
}
|
||||||
|
}
|
68
hibernate-ehcache/src/main/java/org/hibernate/cache/ehcache/internal/HibernateEhcacheUtils.java
vendored
Normal file
68
hibernate-ehcache/src/main/java/org/hibernate/cache/ehcache/internal/HibernateEhcacheUtils.java
vendored
Normal file
|
@ -0,0 +1,68 @@
|
||||||
|
/*
|
||||||
|
* 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.internal;
|
||||||
|
|
||||||
|
import java.net.URL;
|
||||||
|
|
||||||
|
import net.sf.ehcache.config.CacheConfiguration;
|
||||||
|
import net.sf.ehcache.config.Configuration;
|
||||||
|
import net.sf.ehcache.config.ConfigurationFactory;
|
||||||
|
import net.sf.ehcache.config.NonstopConfiguration;
|
||||||
|
import net.sf.ehcache.config.TimeoutBehaviorConfiguration.TimeoutBehaviorType;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Copy of Ehcache utils into Hibernate code base
|
||||||
|
*
|
||||||
|
* @author Chris Dennis
|
||||||
|
* @author Abhishek Sanoujam
|
||||||
|
* @author Alex Snaps
|
||||||
|
*/
|
||||||
|
public final class HibernateEhcacheUtils {
|
||||||
|
|
||||||
|
private HibernateEhcacheUtils() {
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a cache manager configuration from the supplied url, correcting it for Hibernate compatibility.
|
||||||
|
* <p/>
|
||||||
|
* Currently "correcting" for Hibernate compatibility means simply switching any identity based value modes
|
||||||
|
* to serialization.
|
||||||
|
*
|
||||||
|
* @param url The url to load the config from
|
||||||
|
*
|
||||||
|
* @return The Ehcache Configuration object
|
||||||
|
*/
|
||||||
|
public static Configuration loadAndCorrectConfiguration(URL url) {
|
||||||
|
final Configuration config = ConfigurationFactory.parseConfiguration( url );
|
||||||
|
|
||||||
|
// EHC-875 / HHH-6576
|
||||||
|
if ( config == null ) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( config.getDefaultCacheConfiguration() != null
|
||||||
|
&& config.getDefaultCacheConfiguration().isTerracottaClustered() ) {
|
||||||
|
setupHibernateTimeoutBehavior(
|
||||||
|
config.getDefaultCacheConfiguration()
|
||||||
|
.getTerracottaConfiguration()
|
||||||
|
.getNonstopConfiguration()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
for ( CacheConfiguration cacheConfig : config.getCacheConfigurations().values() ) {
|
||||||
|
if ( cacheConfig.isTerracottaClustered() ) {
|
||||||
|
setupHibernateTimeoutBehavior( cacheConfig.getTerracottaConfiguration().getNonstopConfiguration() );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return config;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void setupHibernateTimeoutBehavior(NonstopConfiguration nonstopConfig) {
|
||||||
|
nonstopConfig.getTimeoutBehavior().setType( TimeoutBehaviorType.EXCEPTION.getTypeName() );
|
||||||
|
}
|
||||||
|
}
|
36
hibernate-ehcache/src/main/java/org/hibernate/cache/ehcache/internal/QueryResultsRegionImpl.java
vendored
Normal file
36
hibernate-ehcache/src/main/java/org/hibernate/cache/ehcache/internal/QueryResultsRegionImpl.java
vendored
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
/*
|
||||||
|
* 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.internal;
|
||||||
|
|
||||||
|
import net.sf.ehcache.Cache;
|
||||||
|
|
||||||
|
import org.hibernate.cache.spi.QueryResultsRegion;
|
||||||
|
import org.hibernate.cache.spi.RegionFactory;
|
||||||
|
import org.hibernate.cache.spi.support.DirectAccessRegionTemplate;
|
||||||
|
import org.hibernate.cache.spi.support.StorageAccess;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Chris Dennis
|
||||||
|
* @author Alex Snaps
|
||||||
|
* @author Steve Ebersole
|
||||||
|
*/
|
||||||
|
public class QueryResultsRegionImpl extends DirectAccessRegionTemplate implements QueryResultsRegion {
|
||||||
|
private final StorageAccessImpl cacheAccess;
|
||||||
|
|
||||||
|
public QueryResultsRegionImpl(
|
||||||
|
String name,
|
||||||
|
RegionFactory regionFactory,
|
||||||
|
Cache cache) {
|
||||||
|
super( name, regionFactory );
|
||||||
|
this.cacheAccess = new StorageAccessImpl( cache );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public StorageAccess getStorageAccess() {
|
||||||
|
return cacheAccess;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,87 @@
|
||||||
|
/*
|
||||||
|
* 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.internal;
|
||||||
|
|
||||||
|
import java.net.MalformedURLException;
|
||||||
|
import java.net.URL;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
|
|
||||||
|
import net.sf.ehcache.Cache;
|
||||||
|
import net.sf.ehcache.CacheManager;
|
||||||
|
import net.sf.ehcache.config.Configuration;
|
||||||
|
|
||||||
|
import org.hibernate.boot.spi.SessionFactoryOptions;
|
||||||
|
import org.hibernate.cache.CacheException;
|
||||||
|
import org.hibernate.engine.config.spi.ConfigurationService;
|
||||||
|
|
||||||
|
import org.jboss.logging.Logger;
|
||||||
|
|
||||||
|
import static org.hibernate.cache.ehcache.ConfigSettings.EHCACHE_CONFIGURATION_RESOURCE_NAME;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Steve Ebersole
|
||||||
|
*/
|
||||||
|
public class SingletonEhcacheRegionFactory extends EhcacheRegionFactory {
|
||||||
|
private static final Logger LOG = Logger.getLogger( SingletonEhcacheRegionFactory.class );
|
||||||
|
|
||||||
|
private static final AtomicInteger REFERENCE_COUNT = new AtomicInteger();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected CacheManager resolveCacheManager(SessionFactoryOptions settings, Map properties) {
|
||||||
|
try {
|
||||||
|
String configurationResourceName = getOptions().getServiceRegistry()
|
||||||
|
.getService( ConfigurationService.class )
|
||||||
|
.getSetting( EHCACHE_CONFIGURATION_RESOURCE_NAME, value -> value == null ? null : value.toString() );
|
||||||
|
|
||||||
|
if ( configurationResourceName == null || configurationResourceName.length() == 0 ) {
|
||||||
|
try {
|
||||||
|
REFERENCE_COUNT.incrementAndGet();
|
||||||
|
return CacheManager.create();
|
||||||
|
}
|
||||||
|
catch (RuntimeException e) {
|
||||||
|
REFERENCE_COUNT.decrementAndGet();
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
URL url;
|
||||||
|
try {
|
||||||
|
url = new URL( configurationResourceName );
|
||||||
|
}
|
||||||
|
catch (MalformedURLException e) {
|
||||||
|
if ( !configurationResourceName.startsWith( "/" ) ) {
|
||||||
|
configurationResourceName = "/" + configurationResourceName;
|
||||||
|
LOG.debugf(
|
||||||
|
"prepending / to %s. It should be placed in the root of the classpath rather than in a package.",
|
||||||
|
configurationResourceName
|
||||||
|
);
|
||||||
|
}
|
||||||
|
url = loadResource( configurationResourceName );
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
REFERENCE_COUNT.incrementAndGet();
|
||||||
|
return CacheManager.create( HibernateEhcacheUtils.loadAndCorrectConfiguration( url ) );
|
||||||
|
}
|
||||||
|
catch (RuntimeException e) {
|
||||||
|
REFERENCE_COUNT.decrementAndGet();
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (net.sf.ehcache.CacheException e) {
|
||||||
|
throw new CacheException( e );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void releaseCacheManager() {
|
||||||
|
if ( REFERENCE_COUNT.decrementAndGet() == 0 ) {
|
||||||
|
getCacheManager().shutdown();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
137
hibernate-ehcache/src/main/java/org/hibernate/cache/ehcache/internal/StorageAccessImpl.java
vendored
Normal file
137
hibernate-ehcache/src/main/java/org/hibernate/cache/ehcache/internal/StorageAccessImpl.java
vendored
Normal file
|
@ -0,0 +1,137 @@
|
||||||
|
/*
|
||||||
|
* 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.internal;
|
||||||
|
|
||||||
|
import net.sf.ehcache.Cache;
|
||||||
|
import net.sf.ehcache.Element;
|
||||||
|
import net.sf.ehcache.constructs.nonstop.NonStopCacheException;
|
||||||
|
import net.sf.ehcache.hibernate.nonstop.HibernateNonstopCacheExceptionHandler;
|
||||||
|
|
||||||
|
import org.hibernate.cache.CacheException;
|
||||||
|
import org.hibernate.cache.spi.support.StorageAccess;
|
||||||
|
|
||||||
|
import org.jboss.logging.Logger;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Steve Ebersole
|
||||||
|
*/
|
||||||
|
public class StorageAccessImpl implements StorageAccess {
|
||||||
|
private static final Logger LOG = Logger.getLogger( StorageAccessImpl.class );
|
||||||
|
|
||||||
|
private final Cache cache;
|
||||||
|
|
||||||
|
public StorageAccessImpl(Cache cache) {
|
||||||
|
this.cache = cache;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Cache getCache() {
|
||||||
|
return cache;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object getFromCache(Object key) {
|
||||||
|
try {
|
||||||
|
final Element element = getCache().get( key );
|
||||||
|
if ( element == null ) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return element.getObjectValue();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (net.sf.ehcache.CacheException e) {
|
||||||
|
if ( e instanceof NonStopCacheException ) {
|
||||||
|
HibernateNonstopCacheExceptionHandler.getInstance()
|
||||||
|
.handleNonstopCacheException( (NonStopCacheException) e );
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
throw new CacheException( e );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void putIntoCache(Object key, Object value) {
|
||||||
|
try {
|
||||||
|
final Element element = new Element( key, value );
|
||||||
|
getCache().put( element );
|
||||||
|
}
|
||||||
|
catch (IllegalArgumentException | IllegalStateException e) {
|
||||||
|
throw new CacheException( e );
|
||||||
|
}
|
||||||
|
catch (net.sf.ehcache.CacheException e) {
|
||||||
|
if ( e instanceof NonStopCacheException ) {
|
||||||
|
HibernateNonstopCacheExceptionHandler.getInstance()
|
||||||
|
.handleNonstopCacheException( (NonStopCacheException) e );
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
throw new CacheException( e );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void removeFromCache(Object key) {
|
||||||
|
try {
|
||||||
|
getCache().remove( key );
|
||||||
|
}
|
||||||
|
catch (ClassCastException | IllegalStateException e) {
|
||||||
|
throw new CacheException( e );
|
||||||
|
}
|
||||||
|
catch (net.sf.ehcache.CacheException e) {
|
||||||
|
if ( e instanceof NonStopCacheException ) {
|
||||||
|
HibernateNonstopCacheExceptionHandler.getInstance()
|
||||||
|
.handleNonstopCacheException( (NonStopCacheException) e );
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
throw new CacheException( e );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void clearCache() {
|
||||||
|
try {
|
||||||
|
getCache().removeAll();
|
||||||
|
}
|
||||||
|
catch (IllegalStateException e) {
|
||||||
|
throw new CacheException( e );
|
||||||
|
}
|
||||||
|
catch (net.sf.ehcache.CacheException e) {
|
||||||
|
if ( e instanceof NonStopCacheException ) {
|
||||||
|
HibernateNonstopCacheExceptionHandler.getInstance()
|
||||||
|
.handleNonstopCacheException( (NonStopCacheException) e );
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
throw new CacheException( e );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void release() {
|
||||||
|
try {
|
||||||
|
getCache().getCacheManager().removeCache( getCache().getName() );
|
||||||
|
}
|
||||||
|
catch (IllegalStateException e) {
|
||||||
|
//When Spring and Hibernate are both involved this will happen in normal shutdown operation.
|
||||||
|
//Do not throw an exception, simply log this one.
|
||||||
|
LOG.debug( "This can happen if multiple frameworks both try to shutdown ehcache", e );
|
||||||
|
}
|
||||||
|
catch (net.sf.ehcache.CacheException e) {
|
||||||
|
if ( e instanceof NonStopCacheException ) {
|
||||||
|
HibernateNonstopCacheExceptionHandler.getInstance()
|
||||||
|
.handleNonstopCacheException( (NonStopCacheException) e );
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
throw new CacheException( e );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,57 @@
|
||||||
|
/*
|
||||||
|
* 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.internal;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.hibernate.boot.registry.selector.SimpleStrategyRegistrationImpl;
|
||||||
|
import org.hibernate.boot.registry.selector.StrategyRegistration;
|
||||||
|
import org.hibernate.boot.registry.selector.StrategyRegistrationProvider;
|
||||||
|
import org.hibernate.cache.spi.RegionFactory;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Makes the 2 contained region factory implementations available to the Hibernate
|
||||||
|
* {@link org.hibernate.boot.registry.selector.spi.StrategySelector} service.
|
||||||
|
*
|
||||||
|
* @author Steve Ebersole
|
||||||
|
*/
|
||||||
|
public class StrategyRegistrationProviderImpl implements StrategyRegistrationProvider {
|
||||||
|
@Override
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
public Iterable<StrategyRegistration> getStrategyRegistrations() {
|
||||||
|
final List<StrategyRegistration> strategyRegistrations = new ArrayList<StrategyRegistration>();
|
||||||
|
|
||||||
|
strategyRegistrations.add(
|
||||||
|
new SimpleStrategyRegistrationImpl(
|
||||||
|
RegionFactory.class,
|
||||||
|
EhcacheRegionFactory.class,
|
||||||
|
"ehcache",
|
||||||
|
EhcacheRegionFactory.class.getName(),
|
||||||
|
EhcacheRegionFactory.class.getSimpleName(),
|
||||||
|
// legacy impl class name
|
||||||
|
"org.hibernate.cache.EhCacheRegionFactory",
|
||||||
|
"org.hibernate.cache.ehcache.EhCacheRegionFactory"
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
strategyRegistrations.add(
|
||||||
|
new SimpleStrategyRegistrationImpl(
|
||||||
|
RegionFactory.class,
|
||||||
|
SingletonEhcacheRegionFactory.class,
|
||||||
|
"ehcache-singleton",
|
||||||
|
SingletonEhcacheRegionFactory.class.getName(),
|
||||||
|
SingletonEhcacheRegionFactory.class.getSimpleName(),
|
||||||
|
// legacy impl class name
|
||||||
|
"org.hibernate.cache.SingletonEhCacheRegionFactory",
|
||||||
|
"org.hibernate.cache.ehcache.SingletonEhCacheRegionFactory"
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
return strategyRegistrations;
|
||||||
|
}
|
||||||
|
}
|
38
hibernate-ehcache/src/main/java/org/hibernate/cache/ehcache/internal/TimestampsRegionImpl.java
vendored
Normal file
38
hibernate-ehcache/src/main/java/org/hibernate/cache/ehcache/internal/TimestampsRegionImpl.java
vendored
Normal file
|
@ -0,0 +1,38 @@
|
||||||
|
/*
|
||||||
|
* 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.internal;
|
||||||
|
|
||||||
|
import net.sf.ehcache.Cache;
|
||||||
|
|
||||||
|
import org.hibernate.cache.spi.RegionFactory;
|
||||||
|
import org.hibernate.cache.spi.TimestampsRegion;
|
||||||
|
import org.hibernate.cache.spi.support.DirectAccessRegionTemplate;
|
||||||
|
import org.hibernate.cache.spi.support.StorageAccess;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Access to a JCache Cache used to store "update timestamps".
|
||||||
|
*
|
||||||
|
* @author Chris Dennis
|
||||||
|
* @author Abhishek Sanoujam
|
||||||
|
* @author Alex Snaps
|
||||||
|
*/
|
||||||
|
public class TimestampsRegionImpl extends DirectAccessRegionTemplate implements TimestampsRegion {
|
||||||
|
private final StorageAccessImpl cacheAccess;
|
||||||
|
|
||||||
|
public TimestampsRegionImpl(
|
||||||
|
String regionName,
|
||||||
|
RegionFactory regionFactory,
|
||||||
|
Cache cache) {
|
||||||
|
super( regionName, regionFactory );
|
||||||
|
this.cacheAccess = new StorageAccessImpl( cache );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public StorageAccess getStorageAccess() {
|
||||||
|
return cacheAccess;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,13 @@
|
||||||
|
#
|
||||||
|
# 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
|
||||||
|
#
|
||||||
|
#
|
||||||
|
# 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
|
||||||
|
|
||||||
|
org.hibernate.cache.ehcache.internal.StrategyRegistrationProviderImpl
|
62
hibernate-ehcache/src/test/java/org/hibernate/cache/ehcache/test/SmokeTest.java
vendored
Normal file
62
hibernate-ehcache/src/test/java/org/hibernate/cache/ehcache/test/SmokeTest.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.ehcache.test;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
|
||||||
|
import org.hibernate.boot.registry.BootstrapServiceRegistry;
|
||||||
|
import org.hibernate.boot.registry.BootstrapServiceRegistryBuilder;
|
||||||
|
import org.hibernate.boot.registry.StandardServiceRegistry;
|
||||||
|
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
|
||||||
|
import org.hibernate.boot.registry.selector.spi.StrategySelector;
|
||||||
|
import org.hibernate.cache.ehcache.internal.EhcacheRegionFactory;
|
||||||
|
import org.hibernate.cache.ehcache.internal.SingletonEhcacheRegionFactory;
|
||||||
|
import org.hibernate.cache.spi.RegionFactory;
|
||||||
|
import org.hibernate.cfg.AvailableSettings;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import static org.hamcrest.CoreMatchers.instanceOf;
|
||||||
|
import static org.hamcrest.MatcherAssert.assertThat;
|
||||||
|
import static org.junit.Assert.assertTrue;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Steve Ebersole
|
||||||
|
*/
|
||||||
|
public class SmokeTest {
|
||||||
|
@Test
|
||||||
|
public void testStrategySelectorRegistrations() {
|
||||||
|
final BootstrapServiceRegistry registry = new BootstrapServiceRegistryBuilder().build();
|
||||||
|
final Collection<Class<? extends RegionFactory>> implementors = registry
|
||||||
|
.getService( StrategySelector.class )
|
||||||
|
.getRegisteredStrategyImplementors( RegionFactory.class );
|
||||||
|
assertTrue( implementors.contains( EhcacheRegionFactory.class ) );
|
||||||
|
assertTrue( implementors.contains( SingletonEhcacheRegionFactory.class ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testEhcacheShortName() {
|
||||||
|
final StandardServiceRegistry registry = new StandardServiceRegistryBuilder()
|
||||||
|
.applySetting( AvailableSettings.CACHE_REGION_FACTORY, "ehcache" )
|
||||||
|
.build();
|
||||||
|
assertThat(
|
||||||
|
registry.getService( RegionFactory.class ),
|
||||||
|
instanceOf( EhcacheRegionFactory.class )
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSingletonEhcacheShortName() {
|
||||||
|
final StandardServiceRegistry registry = new StandardServiceRegistryBuilder()
|
||||||
|
.applySetting( AvailableSettings.CACHE_REGION_FACTORY, "ehcache-singleton" )
|
||||||
|
.build();
|
||||||
|
assertThat(
|
||||||
|
registry.getService( RegionFactory.class ),
|
||||||
|
instanceOf( SingletonEhcacheRegionFactory.class )
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,17 @@
|
||||||
|
#
|
||||||
|
# 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
|
||||||
|
#
|
||||||
|
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
|
||||||
|
log4j.appender.stdout.Target=System.out
|
||||||
|
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
|
||||||
|
log4j.appender.stdout.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n
|
||||||
|
|
||||||
|
log4j.rootLogger=info, stdout
|
||||||
|
|
||||||
|
log4j.logger.org.hibernate.test=info
|
||||||
|
|
||||||
|
# SQL Logging - HHH-6833
|
||||||
|
log4j.logger.org.hibernate.SQL=debug
|
|
@ -11,6 +11,7 @@ import org.jboss.logging.annotations.Message;
|
||||||
import org.jboss.logging.annotations.MessageLogger;
|
import org.jboss.logging.annotations.MessageLogger;
|
||||||
|
|
||||||
import org.hibernate.cache.spi.Region;
|
import org.hibernate.cache.spi.Region;
|
||||||
|
import org.hibernate.cache.spi.SecondLevelCacheLogger;
|
||||||
import org.hibernate.internal.CoreMessageLogger;
|
import org.hibernate.internal.CoreMessageLogger;
|
||||||
|
|
||||||
import static org.jboss.logging.Logger.Level.ERROR;
|
import static org.jboss.logging.Logger.Level.ERROR;
|
||||||
|
@ -24,19 +25,27 @@ public interface JCacheMessageLogger extends CoreMessageLogger {
|
||||||
|
|
||||||
static final int NAMESPACE = 40000;
|
static final int NAMESPACE = 40000;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @deprecated (since 5.3) Use {@link SecondLevelCacheLogger#attemptToStartAlreadyStartedCacheProvider()}
|
||||||
|
*/
|
||||||
@LogMessage(level = WARN)
|
@LogMessage(level = WARN)
|
||||||
@Message(
|
@Message(
|
||||||
value = "Attempt to restart an already started JCacheRegionFactory. Use sessionFactory.close() between " +
|
value = "Attempt to restart an already started JCacheRegionFactory. Use sessionFactory.close() between " +
|
||||||
"repeated calls to buildSessionFactory. Using previously created JCacheRegionFactory.",
|
"repeated calls to buildSessionFactory. Using previously created JCacheRegionFactory.",
|
||||||
id = NAMESPACE + 1
|
id = NAMESPACE + 1
|
||||||
)
|
)
|
||||||
|
@Deprecated
|
||||||
void attemptToRestartAlreadyStartedJCacheProvider();
|
void attemptToRestartAlreadyStartedJCacheProvider();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @deprecated (since 5.3) Use {@link SecondLevelCacheLogger#attemptToStopAlreadyStoppedCacheProvider()}
|
||||||
|
*/
|
||||||
@LogMessage(level = WARN)
|
@LogMessage(level = WARN)
|
||||||
@Message(
|
@Message(
|
||||||
value = "Attempt to restop an already stopped JCacheRegionFactory.",
|
value = "Attempt to restop an already stopped JCacheRegionFactory.",
|
||||||
id = NAMESPACE + 2
|
id = NAMESPACE + 2
|
||||||
)
|
)
|
||||||
|
@Deprecated
|
||||||
void attemptToRestopAlreadyStoppedJCacheProvider();
|
void attemptToRestopAlreadyStoppedJCacheProvider();
|
||||||
|
|
||||||
@LogMessage(level = ERROR)
|
@LogMessage(level = ERROR)
|
||||||
|
|
|
@ -26,6 +26,7 @@ import org.hibernate.cache.spi.CacheKeysFactory;
|
||||||
import org.hibernate.cache.spi.DomainDataRegion;
|
import org.hibernate.cache.spi.DomainDataRegion;
|
||||||
import org.hibernate.cache.spi.QueryResultsRegion;
|
import org.hibernate.cache.spi.QueryResultsRegion;
|
||||||
import org.hibernate.cache.spi.RegionFactory;
|
import org.hibernate.cache.spi.RegionFactory;
|
||||||
|
import org.hibernate.cache.spi.SecondLevelCacheLogger;
|
||||||
import org.hibernate.cache.spi.TimestampsRegion;
|
import org.hibernate.cache.spi.TimestampsRegion;
|
||||||
import org.hibernate.cache.spi.access.AccessType;
|
import org.hibernate.cache.spi.access.AccessType;
|
||||||
import org.hibernate.cache.spi.support.RegionNameQualifier;
|
import org.hibernate.cache.spi.support.RegionNameQualifier;
|
||||||
|
@ -98,7 +99,7 @@ public class JCacheRegionFactory implements RegionFactory {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
LOG.attemptToRestartAlreadyStartedJCacheProvider();
|
SecondLevelCacheLogger.INSTANCE.attemptToStartAlreadyStartedCacheProvider();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,41 @@
|
||||||
|
/*
|
||||||
|
* 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.testing.mocks.url;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.net.HttpURLConnection;
|
||||||
|
import java.net.URL;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Steve Ebersole
|
||||||
|
*/
|
||||||
|
public class MockHttpURLConnection extends HttpURLConnection {
|
||||||
|
|
||||||
|
protected MockHttpURLConnection(URL url) {
|
||||||
|
super( url );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public InputStream getInputStream() throws IOException {
|
||||||
|
throw new UnsupportedOperationException( "not yet implemented" );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void connect() throws IOException {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void disconnect() {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean usingProxy() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in New Issue