HHH-11356 - Adjust the 2nd-Cache SPIs to better reflect supported uses

- Fix-ups from Radim's review
- Better Javadoc
This commit is contained in:
Steve Ebersole 2018-03-27 15:38:00 -05:00
parent 94e8ba7ba5
commit b8674563d2
79 changed files with 932 additions and 1144 deletions

View File

@ -15,7 +15,7 @@ import org.hibernate.MultiTenancyStrategy;
import org.hibernate.NullPrecedence;
import org.hibernate.SessionFactory;
import org.hibernate.SessionFactoryObserver;
import org.hibernate.cache.spi.TimestampsRegionAccessFactory;
import org.hibernate.cache.spi.TimestampsCacheFactory;
import org.hibernate.context.spi.CurrentTenantIdentifierResolver;
import org.hibernate.dialect.function.SQLFunction;
import org.hibernate.hql.spi.id.MultiTableBulkIdStrategy;
@ -38,6 +38,7 @@ import java.util.function.Supplier;
*
* @since 5.0
*/
@SuppressWarnings("UnusedReturnValue")
public interface SessionFactoryBuilder {
/**
* Apply a Bean Validation ValidatorFactory to the SessionFactory being built.
@ -491,7 +492,7 @@ public interface SessionFactoryBuilder {
*
* @see org.hibernate.cfg.AvailableSettings#QUERY_CACHE_FACTORY
*/
SessionFactoryBuilder applyTimestampsRegionAccessFactory(TimestampsRegionAccessFactory factory);
SessionFactoryBuilder applyTimestampsCacheFactory(TimestampsCacheFactory factory);
/**
* Apply a prefix to prepended to all cache region names for this SessionFactory.

View File

@ -23,7 +23,7 @@ import org.hibernate.boot.TempTableDdlTransactionHandling;
import org.hibernate.boot.spi.MetadataImplementor;
import org.hibernate.boot.spi.SessionFactoryBuilderImplementor;
import org.hibernate.boot.spi.SessionFactoryOptions;
import org.hibernate.cache.spi.TimestampsRegionAccessFactory;
import org.hibernate.cache.spi.TimestampsCacheFactory;
import org.hibernate.context.spi.CurrentTenantIdentifierResolver;
import org.hibernate.dialect.function.SQLFunction;
import org.hibernate.hql.spi.id.MultiTableBulkIdStrategy;
@ -283,8 +283,8 @@ public class SessionFactoryBuilderImpl implements SessionFactoryBuilderImplement
}
@Override
public SessionFactoryBuilder applyTimestampsRegionAccessFactory(TimestampsRegionAccessFactory factory) {
this.optionsBuilder.applyTimestampsRegionAccessFactory( factory );
public SessionFactoryBuilder applyTimestampsCacheFactory(TimestampsCacheFactory factory) {
this.optionsBuilder.applyTimestampsCacheFactory( factory );
return this;
}

View File

@ -32,9 +32,9 @@ import org.hibernate.boot.TempTableDdlTransactionHandling;
import org.hibernate.boot.registry.StandardServiceRegistry;
import org.hibernate.boot.registry.selector.spi.StrategySelector;
import org.hibernate.boot.spi.SessionFactoryOptions;
import org.hibernate.cache.internal.StandardTimestampsRegionAccessFactory;
import org.hibernate.cache.internal.StandardTimestampsCacheFactory;
import org.hibernate.cache.spi.RegionFactory;
import org.hibernate.cache.spi.TimestampsRegionAccessFactory;
import org.hibernate.cache.spi.TimestampsCacheFactory;
import org.hibernate.cfg.AvailableSettings;
import org.hibernate.cfg.BaselineSessionEventsListenerBuilder;
import org.hibernate.context.spi.CurrentTenantIdentifierResolver;
@ -128,6 +128,7 @@ import static org.hibernate.jpa.AvailableSettings.DISCARD_PC_ON_CLOSE;
*
* @author Steve Ebersole
*/
@SuppressWarnings("WeakerAccess")
public class SessionFactoryOptionsBuilder implements SessionFactoryOptions {
private static final Logger log = Logger.getLogger( SessionFactoryOptionsBuilder.class );
@ -197,7 +198,7 @@ public class SessionFactoryOptionsBuilder implements SessionFactoryOptions {
// Caching
private boolean secondLevelCacheEnabled;
private boolean queryCacheEnabled;
private TimestampsRegionAccessFactory timestampsCacheFactory;
private TimestampsCacheFactory timestampsCacheFactory;
private String cacheRegionPrefix;
private boolean minimalPutsEnabled;
private boolean structuredCacheEntriesEnabled;
@ -332,9 +333,9 @@ public class SessionFactoryOptionsBuilder implements SessionFactoryOptions {
this.secondLevelCacheEnabled = cfgService.getSetting( USE_SECOND_LEVEL_CACHE, BOOLEAN, true );
this.queryCacheEnabled = cfgService.getSetting( USE_QUERY_CACHE, BOOLEAN, false );
this.timestampsCacheFactory = strategySelector.resolveDefaultableStrategy(
TimestampsRegionAccessFactory.class,
TimestampsCacheFactory.class,
configurationSettings.get( QUERY_CACHE_FACTORY ),
StandardTimestampsRegionAccessFactory.INSTANCE
StandardTimestampsCacheFactory.INSTANCE
);
this.cacheRegionPrefix = ConfigurationHelper.extractPropertyValue(
CACHE_REGION_PREFIX,
@ -804,7 +805,7 @@ public class SessionFactoryOptionsBuilder implements SessionFactoryOptions {
}
@Override
public TimestampsRegionAccessFactory getTimestampsRegionAccessFactory() {
public TimestampsCacheFactory getTimestampsCacheFactory() {
return timestampsCacheFactory;
}
@ -1102,7 +1103,7 @@ public class SessionFactoryOptionsBuilder implements SessionFactoryOptions {
this.queryCacheEnabled = enabled;
}
public void applyTimestampsRegionAccessFactory(TimestampsRegionAccessFactory factory) {
public void applyTimestampsCacheFactory(TimestampsCacheFactory factory) {
this.timestampsCacheFactory = factory;
}

View File

@ -17,7 +17,7 @@ import org.hibernate.SessionFactory;
import org.hibernate.SessionFactoryObserver;
import org.hibernate.boot.SessionFactoryBuilder;
import org.hibernate.boot.TempTableDdlTransactionHandling;
import org.hibernate.cache.spi.TimestampsRegionAccessFactory;
import org.hibernate.cache.spi.TimestampsCacheFactory;
import org.hibernate.context.spi.CurrentTenantIdentifierResolver;
import org.hibernate.dialect.function.SQLFunction;
import org.hibernate.hql.spi.id.MultiTableBulkIdStrategy;
@ -279,8 +279,8 @@ public abstract class AbstractDelegatingSessionFactoryBuilder<T extends SessionF
}
@Override
public SessionFactoryBuilder applyTimestampsRegionAccessFactory(TimestampsRegionAccessFactory factory) {
delegate.applyTimestampsRegionAccessFactory( factory );
public SessionFactoryBuilder applyTimestampsCacheFactory(TimestampsCacheFactory factory) {
delegate.applyTimestampsCacheFactory( factory );
return getThis();
}

View File

@ -17,7 +17,7 @@ import org.hibernate.SessionFactoryObserver;
import org.hibernate.boot.SchemaAutoTooling;
import org.hibernate.boot.TempTableDdlTransactionHandling;
import org.hibernate.boot.registry.StandardServiceRegistry;
import org.hibernate.cache.spi.TimestampsRegionAccessFactory;
import org.hibernate.cache.spi.TimestampsCacheFactory;
import org.hibernate.cfg.BaselineSessionEventsListenerBuilder;
import org.hibernate.context.spi.CurrentTenantIdentifierResolver;
import org.hibernate.dialect.function.SQLFunction;
@ -252,8 +252,8 @@ public class AbstractDelegatingSessionFactoryOptions implements SessionFactoryOp
}
@Override
public TimestampsRegionAccessFactory getTimestampsRegionAccessFactory() {
return delegate.getTimestampsRegionAccessFactory();
public TimestampsCacheFactory getTimestampsCacheFactory() {
return delegate.getTimestampsCacheFactory();
}
@Override

View File

@ -22,7 +22,7 @@ import org.hibernate.SessionFactoryObserver;
import org.hibernate.boot.SchemaAutoTooling;
import org.hibernate.boot.TempTableDdlTransactionHandling;
import org.hibernate.boot.registry.StandardServiceRegistry;
import org.hibernate.cache.spi.TimestampsRegionAccessFactory;
import org.hibernate.cache.spi.TimestampsCacheFactory;
import org.hibernate.cfg.BaselineSessionEventsListenerBuilder;
import org.hibernate.context.spi.CurrentTenantIdentifierResolver;
import org.hibernate.dialect.function.SQLFunction;
@ -182,7 +182,7 @@ public interface SessionFactoryOptions {
boolean isQueryCacheEnabled();
TimestampsRegionAccessFactory getTimestampsRegionAccessFactory();
TimestampsCacheFactory getTimestampsCacheFactory();
String getCacheRegionPrefix();

View File

@ -12,10 +12,10 @@ import java.util.Set;
import org.hibernate.cache.cfg.spi.DomainDataRegionConfig;
import org.hibernate.cache.spi.CacheImplementor;
import org.hibernate.cache.spi.QueryResultRegionAccess;
import org.hibernate.cache.spi.QueryResultsCache;
import org.hibernate.cache.spi.Region;
import org.hibernate.cache.spi.RegionFactory;
import org.hibernate.cache.spi.TimestampsRegionAccess;
import org.hibernate.cache.spi.TimestampsCache;
import org.hibernate.cache.spi.access.CollectionDataAccess;
import org.hibernate.cache.spi.access.EntityDataAccess;
import org.hibernate.cache.spi.access.NaturalIdDataAccess;
@ -154,22 +154,22 @@ public class DisabledCaching implements CacheImplementor {
}
@Override
public TimestampsRegionAccess getTimestampsRegionAccess() {
public TimestampsCache getTimestampsCache() {
return null;
}
@Override
public QueryResultRegionAccess getDefaultQueryResultsRegionAccess() {
public QueryResultsCache getDefaultQueryResultsCache() {
return null;
}
@Override
public QueryResultRegionAccess getQueryResultsRegionAccess(String regionName) {
public QueryResultsCache getQueryResultsCache(String regionName) {
return null;
}
@Override
public QueryResultRegionAccess getQueryResultsRegionAccessStrictly(String regionName) {
public QueryResultsCache getQueryResultsCacheStrictly(String regionName) {
return null;
}

View File

@ -25,12 +25,12 @@ import org.hibernate.cache.cfg.spi.NaturalIdDataCachingConfig;
import org.hibernate.cache.spi.CacheImplementor;
import org.hibernate.cache.spi.CacheKeysFactory;
import org.hibernate.cache.spi.DomainDataRegion;
import org.hibernate.cache.spi.QueryResultRegionAccess;
import org.hibernate.cache.spi.QueryResultsCache;
import org.hibernate.cache.spi.QueryResultsRegion;
import org.hibernate.cache.spi.Region;
import org.hibernate.cache.spi.RegionFactory;
import org.hibernate.cache.spi.TimestampsRegion;
import org.hibernate.cache.spi.TimestampsRegionAccess;
import org.hibernate.cache.spi.TimestampsCache;
import org.hibernate.cache.spi.access.CollectionDataAccess;
import org.hibernate.cache.spi.access.EntityDataAccess;
import org.hibernate.cache.spi.access.NaturalIdDataAccess;
@ -61,10 +61,10 @@ public class EnabledCaching implements CacheImplementor, DomainDataRegionBuildin
private final Map<NavigableRole,NaturalIdDataAccess> naturalIdAccessMap = new ConcurrentHashMap<>();
private final Map<NavigableRole,CollectionDataAccess> collectionAccessMap = new ConcurrentHashMap<>();
private final TimestampsRegionAccess timestampsRegionAccess;
private final TimestampsCache timestampsCache;
private final QueryResultRegionAccess defaultQueryResultsRegionAccess;
private final Map<String, QueryResultRegionAccess> namedQueryResultsRegionAccess = new ConcurrentHashMap<>();
private final QueryResultsCache defaultQueryResultsCache;
private final Map<String, QueryResultsCache> namedQueryResultsCacheMap = new ConcurrentHashMap<>();
private final Set<String> legacySecondLevelCacheNames = new LinkedHashSet<>();
@ -81,9 +81,9 @@ public class EnabledCaching implements CacheImplementor, DomainDataRegionBuildin
TimestampsRegion.class.getName(),
sessionFactory
);
timestampsRegionAccess = sessionFactory.getSessionFactoryOptions()
.getTimestampsRegionAccessFactory()
.buildTimestampsRegionAccess( this, timestampsRegion );
timestampsCache = sessionFactory.getSessionFactoryOptions()
.getTimestampsCacheFactory()
.buildTimestampsCache( this, timestampsRegion );
legacySecondLevelCacheNames.add( timestampsRegion.getName() );
final QueryResultsRegion queryResultsRegion = regionFactory.buildQueryResultsRegion(
@ -91,14 +91,14 @@ public class EnabledCaching implements CacheImplementor, DomainDataRegionBuildin
sessionFactory
);
regionsByName.put( queryResultsRegion.getName(), queryResultsRegion );
defaultQueryResultsRegionAccess = new QueryResultRegionAccessImpl(
defaultQueryResultsCache = new QueryResultsCacheImpl(
queryResultsRegion,
timestampsRegionAccess
timestampsCache
);
}
else {
timestampsRegionAccess = new TimestampsRegionAccessDisabledImpl();
defaultQueryResultsRegionAccess = null;
timestampsCache = new TimestampsCacheDisabledImpl();
defaultQueryResultsCache = null;
}
}
@ -197,8 +197,8 @@ public class EnabledCaching implements CacheImplementor, DomainDataRegionBuildin
}
@Override
public TimestampsRegionAccess getTimestampsRegionAccess() {
return timestampsRegionAccess;
public TimestampsCache getTimestampsCache() {
return timestampsCache;
}
@ -410,35 +410,35 @@ public class EnabledCaching implements CacheImplementor, DomainDataRegionBuildin
@Override
public boolean containsQuery(String regionName) {
final QueryResultRegionAccess cacheAccess = getQueryResultsRegionAccessStrictly( regionName );
return cacheAccess != null;
final QueryResultsCache cache = getQueryResultsCacheStrictly( regionName );
return cache != null;
}
@Override
public void evictDefaultQueryRegion() {
evictQueryResultRegion( defaultQueryResultsRegionAccess );
evictQueryResultRegion( defaultQueryResultsCache );
}
@Override
public void evictQueryRegion(String regionName) {
final QueryResultRegionAccess cacheAccess = getQueryResultsRegionAccess( regionName );
if ( cacheAccess == null ) {
final QueryResultsCache cache = getQueryResultsCache( regionName );
if ( cache == null ) {
return;
}
evictQueryResultRegion( cacheAccess );
evictQueryResultRegion( cache );
}
private void evictQueryResultRegion(QueryResultRegionAccess cacheAccess) {
if ( cacheAccess == null ) {
private void evictQueryResultRegion(QueryResultsCache cache) {
if ( cache == null ) {
return;
}
if ( LOG.isDebugEnabled() ) {
LOG.debugf( "Evicting query cache, region: %s", cacheAccess.getRegion().getName() );
LOG.debugf( "Evicting query cache, region: %s", cache.getRegion().getName() );
}
cacheAccess.clear();
cache.clear();
}
@Override
@ -447,30 +447,30 @@ public class EnabledCaching implements CacheImplementor, DomainDataRegionBuildin
LOG.debug( "Evicting cache of all query regions." );
}
evictQueryResultRegion( defaultQueryResultsRegionAccess );
evictQueryResultRegion( defaultQueryResultsCache );
for ( QueryResultRegionAccess cacheAccess : namedQueryResultsRegionAccess.values() ) {
evictQueryResultRegion( cacheAccess );
for ( QueryResultsCache cache : namedQueryResultsCacheMap.values() ) {
evictQueryResultRegion( cache );
}
}
@Override
public QueryResultRegionAccess getDefaultQueryResultsRegionAccess() {
return defaultQueryResultsRegionAccess;
public QueryResultsCache getDefaultQueryResultsCache() {
return defaultQueryResultsCache;
}
@Override
public QueryResultRegionAccess getQueryResultsRegionAccess(String regionName) throws HibernateException {
public QueryResultsCache getQueryResultsCache(String regionName) throws HibernateException {
if ( !getSessionFactory().getSessionFactoryOptions().isQueryCacheEnabled() ) {
return null;
}
if ( regionName == null || regionName.equals( getDefaultQueryResultsRegionAccess().getRegion().getName() ) ) {
return getDefaultQueryResultsRegionAccess();
if ( regionName == null || regionName.equals( getDefaultQueryResultsCache().getRegion().getName() ) ) {
return getDefaultQueryResultsCache();
}
final QueryResultRegionAccess existing = namedQueryResultsRegionAccess.get( regionName );
final QueryResultsCache existing = namedQueryResultsCacheMap.get( regionName );
if ( existing != null ) {
return existing;
}
@ -479,24 +479,24 @@ public class EnabledCaching implements CacheImplementor, DomainDataRegionBuildin
}
@Override
public QueryResultRegionAccess getQueryResultsRegionAccessStrictly(String regionName) {
public QueryResultsCache getQueryResultsCacheStrictly(String regionName) {
if ( !getSessionFactory().getSessionFactoryOptions().isQueryCacheEnabled() ) {
return null;
}
return namedQueryResultsRegionAccess.get( regionName );
return namedQueryResultsCacheMap.get( regionName );
}
protected QueryResultRegionAccess makeQueryResultsRegionAccess(String regionName) {
protected QueryResultsCache makeQueryResultsRegionAccess(String regionName) {
final QueryResultsRegion region = (QueryResultsRegion) regionsByName.computeIfAbsent(
regionName,
this::makeQueryResultsRegion
);
final QueryResultRegionAccessImpl regionAccess = new QueryResultRegionAccessImpl(
final QueryResultsCacheImpl regionAccess = new QueryResultsCacheImpl(
region,
timestampsRegionAccess
timestampsCache
);
namedQueryResultsRegionAccess.put( regionName, regionAccess );
namedQueryResultsCacheMap.put( regionName, regionAccess );
legacySecondLevelCacheNames.add( regionName );
return regionAccess;
}

View File

@ -12,12 +12,11 @@ import java.util.List;
import java.util.Set;
import org.hibernate.HibernateException;
import org.hibernate.cache.CacheException;
import org.hibernate.cache.spi.QueryKey;
import org.hibernate.cache.spi.QueryResultRegionAccess;
import org.hibernate.cache.spi.QueryResultsCache;
import org.hibernate.cache.spi.QueryResultsRegion;
import org.hibernate.cache.spi.QuerySpacesHelper;
import org.hibernate.cache.spi.TimestampsRegionAccess;
import org.hibernate.cache.spi.TimestampsCache;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.internal.CoreLogging;
import org.hibernate.internal.CoreMessageLogger;
@ -27,24 +26,24 @@ import org.hibernate.type.TypeHelper;
/**
* The standard implementation of the Hibernate QueryCache interface. Works
* hind-in-hand with {@link TimestampsRegionAccess} to help in recognizing
* hind-in-hand with {@link TimestampsCache} to help in recognizing
* stale query results.
*
* @author Gavin King
* @author Steve Ebersole
*/
public class QueryResultRegionAccessImpl implements QueryResultRegionAccess {
private static final CoreMessageLogger LOG = CoreLogging.messageLogger( QueryResultRegionAccessImpl.class );
public class QueryResultsCacheImpl implements QueryResultsCache {
private static final CoreMessageLogger LOG = CoreLogging.messageLogger( QueryResultsCacheImpl.class );
private static final boolean DEBUGGING = LOG.isDebugEnabled();
private static final boolean TRACING = LOG.isTraceEnabled();
private final QueryResultsRegion cacheRegion;
private final TimestampsRegionAccess timestampsCache;
private final TimestampsCache timestampsCache;
QueryResultRegionAccessImpl(
QueryResultsCacheImpl(
QueryResultsRegion cacheRegion,
TimestampsRegionAccess timestampsCache) {
TimestampsCache timestampsCache) {
this.cacheRegion = cacheRegion;
this.timestampsCache = timestampsCache;
}
@ -93,7 +92,7 @@ public class QueryResultRegionAccessImpl implements QueryResultRegionAccess {
try {
session.getEventListenerManager().cachePutStart();
cacheRegion.putIntoCache( key, cacheItem );
cacheRegion.putIntoCache( key, cacheItem, session );
}
finally {
session.getEventListenerManager().cachePutEnd();
@ -189,7 +188,7 @@ public class QueryResultRegionAccessImpl implements QueryResultRegionAccess {
CacheItem cachedItem = null;
try {
session.getEventListenerManager().cacheGetStart();
cachedItem = (CacheItem) cacheRegion.getFromCache( key );
cachedItem = (CacheItem) cacheRegion.getFromCache( key, session );
}
finally {
session.getEventListenerManager().cacheGetEnd( cachedItem != null );

View File

@ -7,24 +7,24 @@
package org.hibernate.cache.internal;
import org.hibernate.cache.spi.CacheImplementor;
import org.hibernate.cache.spi.TimestampsRegionAccess;
import org.hibernate.cache.spi.TimestampsRegionAccessFactory;
import org.hibernate.cache.spi.TimestampsCache;
import org.hibernate.cache.spi.TimestampsCacheFactory;
import org.hibernate.cache.spi.TimestampsRegion;
/**
* Standard Hibernate implementation of the QueryCacheFactory interface. Returns instances of
* {@link QueryResultRegionAccessImpl}.
* {@link QueryResultsCacheImpl}.
*/
public class StandardTimestampsRegionAccessFactory implements TimestampsRegionAccessFactory {
public class StandardTimestampsCacheFactory implements TimestampsCacheFactory {
/**
* Singleton access
*/
public static final StandardTimestampsRegionAccessFactory INSTANCE = new StandardTimestampsRegionAccessFactory();
public static final StandardTimestampsCacheFactory INSTANCE = new StandardTimestampsCacheFactory();
@Override
public TimestampsRegionAccess buildTimestampsRegionAccess(
public TimestampsCache buildTimestampsCache(
CacheImplementor cacheManager,
TimestampsRegion timestampsRegion) {
return new TimestampsRegionAccessEnabledImpl( timestampsRegion );
return new TimestampsCacheEnabledImpl( timestampsRegion );
}
}

View File

@ -6,7 +6,7 @@
*/
package org.hibernate.cache.internal;
import org.hibernate.cache.spi.TimestampsRegionAccess;
import org.hibernate.cache.spi.TimestampsCache;
import org.hibernate.cache.spi.TimestampsRegion;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
@ -18,8 +18,8 @@ import org.jboss.logging.Logger;
*
* @author Steve Ebersole
*/
public class TimestampsRegionAccessDisabledImpl implements TimestampsRegionAccess {
private static final Logger log = Logger.getLogger( TimestampsRegionAccessDisabledImpl.class );
public class TimestampsCacheDisabledImpl implements TimestampsCache {
private static final Logger log = Logger.getLogger( TimestampsCacheDisabledImpl.class );
@Override
public TimestampsRegion getRegion() {

View File

@ -10,24 +10,24 @@ import java.io.Serializable;
import org.hibernate.cache.spi.RegionFactory;
import org.hibernate.cache.spi.TimestampsRegion;
import org.hibernate.cache.spi.TimestampsRegionAccess;
import org.hibernate.cache.spi.TimestampsCache;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.jboss.logging.Logger;
/**
* Standard implementation of QuerySpaceStalenessStrategy
* Standard implementation of TimestampsCache
*
* @author Steve Ebersole
*/
public class TimestampsRegionAccessEnabledImpl implements TimestampsRegionAccess {
private static final Logger log = Logger.getLogger( TimestampsRegionAccessEnabledImpl.class );
public class TimestampsCacheEnabledImpl implements TimestampsCache {
private static final Logger log = Logger.getLogger( TimestampsCacheEnabledImpl.class );
private static final boolean DEBUG_ENABLED = log.isDebugEnabled();
private final TimestampsRegion timestampsRegion;
public TimestampsRegionAccessEnabledImpl(TimestampsRegion timestampsRegion) {
public TimestampsCacheEnabledImpl(TimestampsRegion timestampsRegion) {
this.timestampsRegion = timestampsRegion;
}
@ -57,7 +57,7 @@ public class TimestampsRegionAccessEnabledImpl implements TimestampsRegionAccess
//put() has nowait semantics, is this really appropriate?
//note that it needs to be async replication, never local or sync
timestampsRegion.putIntoCache( space, ts );
timestampsRegion.putIntoCache( space, ts, session );
}
finally {
session.getEventListenerManager().cachePutEnd();
@ -84,7 +84,7 @@ public class TimestampsRegionAccessEnabledImpl implements TimestampsRegionAccess
try {
session.getEventListenerManager().cachePutStart();
timestampsRegion.putIntoCache( space, ts );
timestampsRegion.putIntoCache( space, ts, session );
}
finally {
session.getEventListenerManager().cachePutEnd();
@ -135,7 +135,7 @@ public class TimestampsRegionAccessEnabledImpl implements TimestampsRegionAccess
Long ts = null;
try {
session.getEventListenerManager().cacheGetStart();
ts = (Long) timestampsRegion.getFromCache( space );
ts = (Long) timestampsRegion.getFromCache( space, session );
}
finally {
session.getEventListenerManager().cacheGetEnd( ts != null );

View File

@ -0,0 +1,131 @@
/*
* 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.spi;
import java.util.Map;
import java.util.concurrent.atomic.AtomicBoolean;
import org.hibernate.boot.spi.SessionFactoryOptions;
import org.hibernate.cache.CacheException;
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.SharedSessionContractImplementor;
/**
* @author Steve Ebersole
*/
public abstract class AbstractRegionFactory implements RegionFactory {
private final AtomicBoolean started = new AtomicBoolean( false );
private SessionFactoryOptions options;
protected boolean isStarted() {
if ( started.get() ) {
assert options != null;
return true;
}
else {
assert options == null;
throw new IllegalStateException( "Cache provider not started" );
}
}
protected void verifyStarted() {
if ( ! verifiedStartStatus() ) {
throw new IllegalStateException( "Cache provider not started" );
}
}
protected boolean verifiedStartStatus() {
if ( started.get() ) {
assert options != null;
return true;
}
else {
assert options == null;
return false;
}
}
protected SessionFactoryOptions getOptions() {
verifyStarted();
return options;
}
@Override
public final void start(SessionFactoryOptions settings, Map configValues) throws CacheException {
if ( started.compareAndSet( false, true ) ) {
synchronized (this) {
this.options = settings;
try {
prepareForUse( settings, configValues );
}
catch ( Exception e ) {
options = null;
started.set( false );
}
}
}
else {
SecondLevelCacheLogger.INSTANCE.attemptToStartAlreadyStartedCacheProvider();
}
}
protected abstract void prepareForUse(SessionFactoryOptions settings, Map configValues);
@Override
public final void stop() {
if ( started.compareAndSet( true, false ) ) {
synchronized ( this ) {
try {
releaseFromUse();
}
finally {
options = null;
}
}
}
else {
SecondLevelCacheLogger.INSTANCE.attemptToStopAlreadyStoppedCacheProvider();
}
}
protected abstract void releaseFromUse();
@Override
public boolean isMinimalPutsEnabledByDefault() {
return false;
}
@Override
public AccessType getDefaultAccessType() {
return AccessType.READ_WRITE;
}
@Override
public String qualify(String regionName) {
return RegionNameQualifier.INSTANCE.qualify( regionName, options );
}
@Override
public CacheTransactionSynchronization createTransactionContext(SharedSessionContractImplementor session) {
return new StandardCacheTransactionSynchronization( this );
}
@Override
public long nextTimestamp() {
return SimpleTimestamper.next();
}
@Override
public long getTimeout() {
return SimpleTimestamper.timeOut();
}
}

View File

@ -74,14 +74,14 @@ public interface CacheImplementor extends Service, Cache, org.hibernate.engine.s
*
* @since 5.3
*/
TimestampsRegionAccess getTimestampsRegionAccess();
TimestampsCache getTimestampsCache();
/**
* Access to the "default" region used to store query results when caching
* was requested but no region was explicitly named. Will return {@code null}
* if Hibernate is not configured for query result caching
*/
QueryResultRegionAccess getDefaultQueryResultsRegionAccess();
QueryResultsCache getDefaultQueryResultsCache();
/**
* Get query cache by <tt>region name</tt> or create a new one if none exist.
@ -90,7 +90,7 @@ public interface CacheImplementor extends Service, Cache, org.hibernate.engine.s
*
* Will return {@code null} if Hibernate is not configured for query result caching
*/
QueryResultRegionAccess getQueryResultsRegionAccess(String regionName);
QueryResultsCache getQueryResultsCache(String regionName);
/**
* Get the named QueryResultRegionAccess but not creating one if it
@ -101,13 +101,13 @@ public interface CacheImplementor extends Service, Cache, org.hibernate.engine.s
*
* @since 5.3
*/
QueryResultRegionAccess getQueryResultsRegionAccessStrictly(String regionName);
QueryResultsCache getQueryResultsCacheStrictly(String regionName);
/**
* Clean up the default query cache
*/
default void evictQueries() throws HibernateException {
QueryResultRegionAccess cache = getDefaultQueryResultsRegionAccess();
QueryResultsCache cache = getDefaultQueryResultsCache();
if ( cache != null ) {
cache.clear();
}
@ -177,39 +177,39 @@ public interface CacheImplementor extends Service, Cache, org.hibernate.engine.s
/**
* Get {@code UpdateTimestampsCache} instance managed by the {@code SessionFactory}.
*
* @deprecated Use {@link #getTimestampsRegionAccess} instead
* @deprecated Use {@link #getTimestampsCache} instead
*/
@Deprecated
default UpdateTimestampsCache getUpdateTimestampsCache() {
return getTimestampsRegionAccess();
return getTimestampsCache();
}
/**
* Get the default {@code QueryCache}.
*
* @deprecated Use {@link #getDefaultQueryResultsRegionAccess} instead.
* @deprecated Use {@link #getDefaultQueryResultsCache} instead.
*/
@Deprecated
default QueryCache getQueryCache() {
return getDefaultQueryResultsRegionAccess();
return getDefaultQueryResultsCache();
}
/**
* Get the default {@code QueryCache}.
*
* @deprecated Use {@link #getDefaultQueryResultsRegionAccess} instead.
* @deprecated Use {@link #getDefaultQueryResultsCache} instead.
*/
@Deprecated
default QueryCache getDefaultQueryCache() {
return getDefaultQueryResultsRegionAccess();
return getDefaultQueryResultsCache();
}
/**
* @deprecated Use {@link #getQueryResultsRegionAccess(String)} instead, but using unqualified name
* @deprecated Use {@link #getQueryResultsCache(String)} instead, but using unqualified name
*/
@Deprecated
default QueryCache getQueryCache(String regionName) throws HibernateException {
return getQueryResultsRegionAccess( unqualifyRegionName( regionName ) );
return getQueryResultsCache( unqualifyRegionName( regionName ) );
}

View File

@ -6,20 +6,20 @@
*/
package org.hibernate.cache.spi;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
/**
* Specialized Region whose data is accessed directly - not requiring
* Specialized Region whose data is accessed directly (not requiring
* key/item wrapping, e.g.
*
* @author Steve Ebersole
*/
public interface DirectAccessRegion extends Region {
default boolean contains(Object key) {
return getFromCache( key ) != null;
}
boolean contains(Object key);
Object getFromCache(Object key);
Object getFromCache(Object key, SharedSessionContractImplementor session);
void putIntoCache(Object key, Object value);
void putIntoCache(Object key, Object value, SharedSessionContractImplementor session);
void removeFromCache(Object key);
void removeFromCache(Object key, SharedSessionContractImplementor session);
}

View File

@ -12,7 +12,13 @@ import org.hibernate.cache.spi.access.NaturalIdDataAccess;
import org.hibernate.metamodel.model.domain.NavigableRole;
/**
* A Region for cacheable domain data - entity, collection, natural-id
* A Region for cacheable domain data - entity, collection, natural-id.
*
* Generally speaking, this type of data has:
*
* * specific key and value wrapping that needs to be applied
* * specific access patterns ({@link EntityDataAccess}, etc),
* including some form of locking
*
* @author Steve Ebersole
*/

View File

@ -17,8 +17,8 @@ import org.hibernate.type.Type;
/**
* @author Steve Ebersole
*
* @deprecated Use {@link QueryResultRegionAccess} instead -
* {@link CacheImplementor#getQueryResultsRegionAccess} rather than
* @deprecated Use {@link QueryResultsCache} instead -
* {@link CacheImplementor#getQueryResultsCache} rather than
* {@link CacheImplementor#getQueryCache}
*/
@Deprecated

View File

@ -22,7 +22,7 @@ import org.hibernate.type.Type;
* @author Gavin King
* @author Steve Ebersole
*/
public interface QueryResultRegionAccess extends QueryCache {
public interface QueryResultsCache extends QueryCache {
/**
* The underlying cache region being used.
*/

View File

@ -9,19 +9,28 @@ package org.hibernate.cache.spi;
import org.hibernate.cache.CacheException;
/**
* Defines a contract for accessing a particular named region within the
* underlying cache implementation.
* Contract for a named "region". The concept of a Region might not
* necessarily correlate to a specific concept in the underlying caching
* provider - it is just a thing that can be referenced by name later.
*
* Region is the base contract defining some common characteristics
* regardless of the type of data intended to be stored within this
* Region. The more specific sub-types are {@link DomainDataRegion}
* (storing entity, collection and natural-id data) and
* {@link DirectAccessRegion} (storing query result and timestamp
* data).
*
* @author Steve Ebersole
*/
public interface Region {
/**
* Retrieve the name of this region.
*
* @return The region name
*/
String getName();
/**
* The RegionFactory that generated this Region
*/
RegionFactory getRegionFactory();
/**

View File

@ -18,12 +18,15 @@ import org.hibernate.engine.spi.SharedSessionContractImplementor;
*
* @author Steve Ebersole
*/
public interface TimestampsRegionAccess extends UpdateTimestampsCache {
public interface TimestampsCache extends UpdateTimestampsCache {
/**
* The region used to store all timestamps data
*/
TimestampsRegion getRegion();
/**
* Perform pre-invalidation of the passed spaces (table names)
* using the passed region for storing update-timestamps
* against the timestamps region data
*/
void preInvalidate(
String[] spaces,
@ -31,7 +34,7 @@ public interface TimestampsRegionAccess extends UpdateTimestampsCache {
/**
* Perform invalidation of the passed spaces (table names)
* using the passed region for storing update-timestamps
* against the timestamps region data
*/
void invalidate(
String[] spaces,

View File

@ -8,10 +8,14 @@ package org.hibernate.cache.spi;
/**
* Responsible for building the TimestampsRegionAccessFactory to use for
* managing query results in regards to staleness
* managing query results in regards to staleness of the underlying
* tables (sometimes called "query spaces" or "table spaces")
*
* @author Steve Ebersole
*/
public interface TimestampsRegionAccessFactory {
TimestampsRegionAccess buildTimestampsRegionAccess(CacheImplementor cacheManager, TimestampsRegion timestampsRegion);
public interface TimestampsCacheFactory {
/**
* Build the TimestampsCache
*/
TimestampsCache buildTimestampsCache(CacheImplementor cacheManager, TimestampsRegion timestampsRegion);
}

View File

@ -22,7 +22,7 @@ import org.hibernate.engine.spi.SharedSessionContractImplementor;
* @author Gavin King
* @author Mikheil Kapanadze
*
* @deprecated Use {@link TimestampsRegionAccess} instead
* @deprecated Use {@link TimestampsCache} instead
*/
@SuppressWarnings("unused")
@Deprecated

View File

@ -0,0 +1,39 @@
/*
* 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
*/
/**
* Defines the integration aspect of Hibernate's second-level
* caching allowing "caching back ends" to be plugged in as
* a caching provider.
*
* {@link org.hibernate.cache.spi.RegionFactory} is the main
* integration contract that defines how Hibernate accesses
* the provider. It's main contract is the generation of
* {@link org.hibernate.cache.spi.Region} references with the
* requested intent (what will be stored there).
*
* Generally a provider will integrate with Hibernate by:
*
* 1. implementing the contracts in {@link org.hibernate.cache.spi}
* 2. implementing the contracts in {@link org.hibernate.cache.spi.support}
* 3. a mix of (1) and (2)
*
* The first approach allows for more control of the set up, but also requires more
* to implement. The second approach tries to minimize the amount of work needed
* to integrate with caching providers to basically the
* {@link org.hibernate.cache.spi.support.StorageAccess} and
* {@link org.hibernate.cache.spi.support.DomainDataStorageAccess} contracts which
* are basic read/write type abstractions of the underlying "cache" object - it
* is a nearly complete implementation aside from providing the proper "storage
* access" objects.
*
* Note: providers may also integrate with Hibernate via
* Hibernate's JCache support as defined by the `hibernate-jcache`
* module - no code involved aside from being a JCache implementation
* properly registered via the JCache spec.
*/
package org.hibernate.cache.spi;

View File

@ -1,20 +0,0 @@
<!--
~ 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>.
-->
<html>
<body>
<p>
Defines the Hibernate second level caching SPI.
</p>
<p>
The initial contract here is {@link org.hibernate.cache.spi.RegionFactory} whose implementations are
responsible for configuring and managing lifecycle operations in regards to the particular underlying
caching library. Its other main purpose is to build specializations {@link org.hibernate.cache.spi.Region}
instances based on the type of data we will be storing in that given region.
</p>
</body>
</html>

View File

@ -34,37 +34,24 @@ public abstract class AbstractCachedDomainDataAccess implements CachedDomainData
return region;
}
protected Object getFromCache(Object key) {
log.debugf( "Locating entry in cache storage [region=`%s`] : %s", key );
return storageAccess.getFromCache( key );
}
@SuppressWarnings({"unchecked", "WeakerAccess"})
protected void addToCache(Object key, Object value) {
log.debugf( "Adding entry to cache storage [region=`%s`] : %s -> %s", getRegion().getName(), key, value );
storageAccess.putIntoCache( key, value );
}
@SuppressWarnings({"unchecked", "WeakerAccess"})
protected void removeFromCache(Object key) {
log.debugf( "Removing entry from cache storage [region=`%s`] : %s", key );
storageAccess.removeFromCache( key );
protected DomainDataStorageAccess getStorageAccess() {
return storageAccess;
}
@SuppressWarnings({"unchecked", "WeakerAccess"})
protected void clearCache() {
log.debugf( "Clearing cache data map [region=`%s`]" );
storageAccess.clearCache();
getStorageAccess().evictData();
}
@Override
public boolean contains(Object key) {
return storageAccess.contains( key );
return getStorageAccess().contains( key );
}
@Override
public Object get(SharedSessionContractImplementor session, Object key) {
return getFromCache( key );
return getStorageAccess().getFromCache( key, session );
}
@Override
@ -73,7 +60,7 @@ public abstract class AbstractCachedDomainDataAccess implements CachedDomainData
Object key,
Object value,
Object version) {
addToCache( key, value );
getStorageAccess().putFromLoad( key, value, session );
return true;
}
@ -102,7 +89,7 @@ public abstract class AbstractCachedDomainDataAccess implements CachedDomainData
@Override
public void remove(SharedSessionContractImplementor session, Object key) {
removeFromCache( key );
getStorageAccess().removeFromCache( key, session );
}
@Override
@ -112,16 +99,16 @@ public abstract class AbstractCachedDomainDataAccess implements CachedDomainData
@Override
public void evict(Object key) {
removeFromCache( key );
getStorageAccess().evictData( key );
}
@Override
public void evictAll() {
clearCache();
getStorageAccess().evictData();
}
@Override
public void destroy() {
storageAccess.release();
getStorageAccess().release();
}
}

View File

@ -51,9 +51,12 @@ public abstract class AbstractDomainDataRegion extends AbstractRegion implements
this.sessionFactory = buildingContext.getSessionFactory();
if ( defaultKeysFactory == null ) {
defaultKeysFactory = DefaultCacheKeysFactory.INSTANCE;
}
this.effectiveKeysFactory = buildingContext.getEnforcedCacheKeysFactory() != null
? buildingContext.getEnforcedCacheKeysFactory()
: defaultKeysFactory != null ? defaultKeysFactory : DefaultCacheKeysFactory.INSTANCE;
: defaultKeysFactory;
}
/**

View File

@ -45,7 +45,7 @@ public abstract class AbstractNaturalIdDataAccess extends AbstractCachedDomainDa
@Override
public boolean insert(SharedSessionContractImplementor session, Object key, Object value) {
addToCache( key, value );
getStorageAccess().putIntoCache( key, value, session );
return true;
}
@ -56,7 +56,7 @@ public abstract class AbstractNaturalIdDataAccess extends AbstractCachedDomainDa
@Override
public boolean update(SharedSessionContractImplementor session, Object key, Object value) {
addToCache( key, value );
getStorageAccess().putIntoCache( key, value, session );
return true;
}

View File

@ -67,7 +67,7 @@ public abstract class AbstractReadWriteAccess extends AbstractCachedDomainDataAc
log.debugf( "Getting cached data from region [`%s` (%s)] by key [%s]", getRegion().getName(), key );
try {
readLock.lock();
Lockable item = (Lockable) getFromCache( key );
Lockable item = (Lockable) getStorageAccess().getFromCache( key, session );
if ( item == null ) {
log.debugf( "Cache miss : region = `%s`, key = `%s`", getRegion().getName(), key );
@ -98,11 +98,15 @@ public abstract class AbstractReadWriteAccess extends AbstractCachedDomainDataAc
try {
log.debugf( "Caching data from load [region=`%s` (%s)] : key[%s] -> value[%s]", getRegion().getName(), getAccessType(), key, value );
writeLock.lock();
Lockable item = (Lockable) getFromCache( key );
Lockable item = (Lockable) getStorageAccess().getFromCache( key, session );
boolean writable = item == null || item.isWriteable( session.getTransactionStartTimestamp(), version, getVersionComparator() );
if ( writable ) {
addToCache( key, new Item( value, version, session.getTransactionStartTimestamp() ) );
getStorageAccess().putIntoCache(
key,
new Item( value, version, session.getTransactionStartTimestamp() ),
session
);
return true;
}
else {
@ -141,11 +145,11 @@ public abstract class AbstractReadWriteAccess extends AbstractCachedDomainDataAc
long timeout = getRegion().getRegionFactory().nextTimestamp() + getRegion().getRegionFactory().getTimeout();
log.debugf( "Locking cache item [region=`%s` (%s)] : `%s` (timeout=%s, version=%s)", getRegion().getName(), getAccessType(), key, timeout, version );
Lockable item = (Lockable) getFromCache( key );
Lockable item = (Lockable) getStorageAccess().getFromCache( key, session );
final SoftLockImpl lock = ( item == null )
? new SoftLockImpl( timeout, uuid, nextLockId(), version )
: item.lock( timeout, uuid, nextLockId() );
addToCache( key, lock );
getStorageAccess().putIntoCache( key, lock, session );
return lock;
}
finally {
@ -158,7 +162,7 @@ public abstract class AbstractReadWriteAccess extends AbstractCachedDomainDataAc
try {
log.debugf( "Unlocking cache item [region=`%s` (%s)] : %s", getRegion().getName(), getAccessType(), key );
writeLock.lock();
Lockable item = (Lockable) getFromCache( key );
Lockable item = (Lockable) getStorageAccess().getFromCache( key, session );
if ( ( item != null ) && item.isUnlockable( lock ) ) {
decrementLock( session, key, (SoftLockImpl) item );
@ -175,7 +179,7 @@ public abstract class AbstractReadWriteAccess extends AbstractCachedDomainDataAc
@SuppressWarnings("WeakerAccess")
protected void decrementLock(SharedSessionContractImplementor session, Object key, SoftLockImpl lock) {
lock.unlock( getRegion().getRegionFactory().nextTimestamp() );
addToCache( key, lock );
getStorageAccess().putIntoCache( key, lock, session );
}
@SuppressWarnings("WeakerAccess")
@ -188,12 +192,12 @@ public abstract class AbstractReadWriteAccess extends AbstractCachedDomainDataAc
SoftLockImpl newLock = new SoftLockImpl( ts, uuid, nextLockId.getAndIncrement(), null );
//newLock.unlock( ts );
newLock.unlock( ts - getRegion().getRegionFactory().getTimeout() );
addToCache( key, newLock );
getStorageAccess().putIntoCache( key, newLock, session );
}
@Override
public void remove(SharedSessionContractImplementor session, Object key) {
if ( getFromCache( key ) instanceof SoftLock ) {
if ( getStorageAccess().getFromCache( key, session ) instanceof SoftLock ) {
log.debugf( "Skipping #remove call in read-write access to maintain SoftLock : %s", key );
// don'tm do anything... we want the SoftLock to remain in place
}

View File

@ -35,6 +35,6 @@ public class CollectionNonStrictReadWriteAccess extends AbstractCollectionDataAc
@Override
public void unlockItem(SharedSessionContractImplementor session, Object key, SoftLock lock) {
removeFromCache( key );
getStorageAccess().removeFromCache( key, session );
}
}

View File

@ -8,16 +8,24 @@ package org.hibernate.cache.spi.support;
import org.hibernate.cache.spi.DirectAccessRegion;
import org.hibernate.cache.spi.RegionFactory;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
/**
* Bridge between DirectAccessRegion and StorageAccess
*
* @author Steve Ebersole
*/
public abstract class DirectAccessRegionTemplate extends AbstractRegion implements DirectAccessRegion {
public DirectAccessRegionTemplate(String name, RegionFactory regionFactory) {
private final StorageAccess storageAccess;
public DirectAccessRegionTemplate(String name, RegionFactory regionFactory, StorageAccess storageAccess) {
super( name, regionFactory );
this.storageAccess = storageAccess;
}
public abstract StorageAccess getStorageAccess();
public StorageAccess getStorageAccess() {
return storageAccess;
}
@Override
public boolean contains(Object key) {
@ -25,23 +33,23 @@ public abstract class DirectAccessRegionTemplate extends AbstractRegion implemen
}
@Override
public Object getFromCache(Object key) {
return getStorageAccess().getFromCache( key );
public Object getFromCache(Object key, SharedSessionContractImplementor session) {
return getStorageAccess().getFromCache( key, session );
}
@Override
public void putIntoCache(Object key, Object value) {
getStorageAccess().putIntoCache( key, value );
public void putIntoCache(Object key, Object value, SharedSessionContractImplementor session) {
getStorageAccess().putIntoCache( key, value, session );
}
@Override
public void removeFromCache(Object key) {
getStorageAccess().removeFromCache( key );
public void removeFromCache(Object key, SharedSessionContractImplementor session) {
getStorageAccess().removeFromCache( key, session );
}
@Override
public void clear() {
getStorageAccess().clearCache();
getStorageAccess().evictData();
}
@Override

View File

@ -34,11 +34,11 @@ import org.jboss.logging.Logger;
* DomainDataStorageAccess reference
* * Custom RegionFactory implementation that creates its custom DomainDataRegionTemplate
*
* todo (5.3.) : move this javadoc into DomainDataRegion and/or package javadoc
* todo (5.3) : move this javadoc into DomainDataRegion and/or package javadoc
*
* @author Steve Ebersole
*/
public abstract class DomainDataRegionTemplate extends AbstractDomainDataRegion {
public class DomainDataRegionTemplate extends AbstractDomainDataRegion {
private static final Logger log = Logger.getLogger( DomainDataRegionTemplate.class );
private final DomainDataStorageAccess storageAccess;
@ -56,7 +56,10 @@ public abstract class DomainDataRegionTemplate extends AbstractDomainDataRegion
completeInstantiation( regionConfig, buildingContext );
}
protected DomainDataStorageAccess getCacheStorageAccess() {
/**
* Public for testing purposes
*/
public DomainDataStorageAccess getCacheStorageAccess() {
return storageAccess;
}

View File

@ -6,9 +6,22 @@
*/
package org.hibernate.cache.spi.support;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
/**
* Specialization of StorageAccess for domain data regions
*
* @author Steve Ebersole
*/
public interface DomainDataStorageAccess extends StorageAccess {
void putFromLoad(Object key, Object value);
/**
* Specialized form of putting something into the cache
* in cases where the put is coming from a load (read) from
* the database
*
* @implNote the method default is to call {@link #putIntoCache}
*/
default void putFromLoad(Object key, Object value, SharedSessionContractImplementor session) {
putIntoCache( key, value, session );
}
}

View File

@ -55,7 +55,7 @@ public class EntityNonStrictReadWriteAccess extends AbstractEntityDataAccess {
Object value,
Object currentVersion,
Object previousVersion) {
removeFromCache( key );
getStorageAccess().removeFromCache( key, session );
return false;
}
@ -76,11 +76,11 @@ public class EntityNonStrictReadWriteAccess extends AbstractEntityDataAccess {
*/
@Override
public void unlockItem(SharedSessionContractImplementor session, Object key, SoftLock lock) throws CacheException {
removeFromCache( key );
getStorageAccess().removeFromCache( key, session );
}
@Override
public void remove(SharedSessionContractImplementor session, Object key) {
removeFromCache( key );
getStorageAccess().removeFromCache( key, session );
}
}

View File

@ -49,7 +49,7 @@ public class EntityReadOnlyAccess extends AbstractEntityDataAccess {
@Override
public boolean afterInsert(SharedSessionContractImplementor session, Object key, Object value, Object version) {
addToCache( key, value );
getStorageAccess().putIntoCache( key, value, session );
return true;
}

View File

@ -82,9 +82,13 @@ public class EntityReadWriteAccess extends AbstractReadWriteAccess implements En
public boolean afterInsert(SharedSessionContractImplementor session, Object key, Object value, Object version) {
try {
writeLock().lock();
Lockable item = (Lockable) getFromCache( key );
Lockable item = (Lockable) getStorageAccess().getFromCache( key, session );
if ( item == null ) {
addToCache( key, new Item( value, version, getRegion().getRegionFactory().nextTimestamp() ) );
getStorageAccess().putIntoCache(
key,
new Item( value, version, getRegion().getRegionFactory().nextTimestamp() ),
session
);
return true;
}
else {
@ -116,7 +120,7 @@ public class EntityReadWriteAccess extends AbstractReadWriteAccess implements En
SoftLock lock) {
try {
writeLock().lock();
Lockable item = (Lockable) getFromCache( key );
Lockable item = (Lockable) getStorageAccess().getFromCache( key, session );
if ( item != null && item.isUnlockable( lock ) ) {
SoftLockImpl lockItem = (SoftLockImpl) item;
@ -125,7 +129,11 @@ public class EntityReadWriteAccess extends AbstractReadWriteAccess implements En
return false;
}
else {
addToCache( key, new Item( value, currentVersion, getRegion().getRegionFactory().nextTimestamp() ) );
getStorageAccess().putIntoCache(
key,
new Item( value, currentVersion, getRegion().getRegionFactory().nextTimestamp() ),
session
);
return true;
}
}

View File

@ -35,12 +35,12 @@ public class NaturalIdNonStrictReadWriteAccess extends AbstractNaturalIdDataAcce
@Override
public void unlockItem(SharedSessionContractImplementor session, Object key, SoftLock lock) {
removeFromCache( key );
getStorageAccess().removeFromCache( key, session );
}
@Override
public void remove(SharedSessionContractImplementor session, Object key) {
removeFromCache( key );
getStorageAccess().removeFromCache( key, session );
}
@Override
@ -55,7 +55,7 @@ public class NaturalIdNonStrictReadWriteAccess extends AbstractNaturalIdDataAcce
@Override
public boolean update(SharedSessionContractImplementor session, Object key, Object value) {
removeFromCache( key );
getStorageAccess().removeFromCache( key, session );
return false;
}
}

View File

@ -73,9 +73,13 @@ public class NaturalIdReadWriteAccess extends AbstractReadWriteAccess implements
public boolean afterInsert(SharedSessionContractImplementor session, Object key, Object value) {
try {
writeLock().lock();
Lockable item = (Lockable) getFromCache( key );
Lockable item = (Lockable) getStorageAccess().getFromCache( key, session );
if ( item == null ) {
addToCache( key, new Item( value, null, getRegion().getRegionFactory().nextTimestamp() ) );
getStorageAccess().putIntoCache(
key,
new Item( value, null, getRegion().getRegionFactory().nextTimestamp() ),
session
);
return true;
}
else {
@ -96,7 +100,7 @@ public class NaturalIdReadWriteAccess extends AbstractReadWriteAccess implements
public boolean afterUpdate(SharedSessionContractImplementor session, Object key, Object value, SoftLock lock) {
try {
writeLock().lock();
Lockable item = (Lockable) getFromCache( key );
Lockable item = (Lockable) getStorageAccess().getFromCache( key, session );
if ( item != null && item.isUnlockable( lock ) ) {
SoftLockImpl lockItem = (SoftLockImpl) item;
@ -105,7 +109,11 @@ public class NaturalIdReadWriteAccess extends AbstractReadWriteAccess implements
return false;
}
else {
addToCache( key, new Item( value, null, getRegion().getRegionFactory().nextTimestamp() ) );
getStorageAccess().putIntoCache(
key,
new Item( value, null, getRegion().getRegionFactory().nextTimestamp() ),
session
);
return true;
}
}

View File

@ -0,0 +1,22 @@
/*
* 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.spi.support;
import org.hibernate.cache.spi.QueryResultsRegion;
import org.hibernate.cache.spi.RegionFactory;
/**
* @author Steve Ebersole
*/
public class QueryResultsRegionTemplate extends DirectAccessRegionTemplate implements QueryResultsRegion {
public QueryResultsRegionTemplate(
String name,
RegionFactory regionFactory,
StorageAccess storageAccess) {
super( name, regionFactory, storageAccess );
}
}

View File

@ -0,0 +1,77 @@
/*
* 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.spi.support;
import org.hibernate.cache.cfg.spi.DomainDataRegionBuildingContext;
import org.hibernate.cache.cfg.spi.DomainDataRegionConfig;
import org.hibernate.cache.internal.DefaultCacheKeysFactory;
import org.hibernate.cache.spi.AbstractRegionFactory;
import org.hibernate.cache.spi.CacheKeysFactory;
import org.hibernate.cache.spi.DomainDataRegion;
import org.hibernate.cache.spi.QueryResultsRegion;
import org.hibernate.cache.spi.TimestampsRegion;
import org.hibernate.engine.spi.SessionFactoryImplementor;
/**
* @author Steve Ebersole
*/
public abstract class RegionFactoryTemplate extends AbstractRegionFactory {
@Override
public DomainDataRegion buildDomainDataRegion(
DomainDataRegionConfig regionConfig,
DomainDataRegionBuildingContext buildingContext) {
verifyStarted();
return new DomainDataRegionTemplate(
regionConfig,
this,
createDomainDataStorageAccess( regionConfig, buildingContext ),
getImplicitCacheKeysFactory(),
buildingContext
);
}
protected CacheKeysFactory getImplicitCacheKeysFactory() {
return DefaultCacheKeysFactory.INSTANCE;
}
protected DomainDataStorageAccess createDomainDataStorageAccess(
DomainDataRegionConfig regionConfig,
DomainDataRegionBuildingContext buildingContext) {
throw new UnsupportedOperationException( "Not implemented by caching provider" );
}
@Override
public QueryResultsRegion buildQueryResultsRegion(
String regionName,
SessionFactoryImplementor sessionFactory) {
verifyStarted();
return new QueryResultsRegionTemplate(
regionName,
this,
createQueryResultsRegionStorageAccess( regionName, sessionFactory )
);
}
protected abstract StorageAccess createQueryResultsRegionStorageAccess(
String regionName,
SessionFactoryImplementor sessionFactory);
@Override
public TimestampsRegion buildTimestampsRegion(
String regionName, SessionFactoryImplementor sessionFactory) {
verifyStarted();
return new TimestampsRegionTemplate(
regionName,
this,
createTimestampsRegionStorageAccess( regionName, sessionFactory )
);
}
protected abstract StorageAccess createTimestampsRegionStorageAccess(
String regionName,
SessionFactoryImplementor sessionFactory);
}

View File

@ -6,22 +6,57 @@
*/
package org.hibernate.cache.spi.support;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
/**
* A general read/write abstraction over the specific "cache"
* object from the caching provider
*
* @author Steve Ebersole
*/
public interface StorageAccess {
default boolean contains(Object key) {
return getFromCache( key ) != null;
/**
* Does the cache contain this key?
*/
boolean contains(Object key);
/**
* Get an item from the cache.
*/
Object getFromCache(Object key, SharedSessionContractImplementor session);
/**
* Put an item into the cache
*/
void putIntoCache(Object key, Object value, SharedSessionContractImplementor session);
/**
* Remove an item from the cache by key
*/
default void removeFromCache(Object key, SharedSessionContractImplementor session) {
evictData( key );
}
Object getFromCache(Object key);
/**
* Clear data from the cache
*/
default void clearCache(SharedSessionContractImplementor session) {
evictData();
}
void putIntoCache(Object key, Object value);
/**
* Clear all data regardless of transaction/locking
*/
void evictData();
void removeFromCache(Object key);
void clearCache();
/**
* Remove the entry regardless of transaction/locking
*/
void evictData(Object key);
/***
* Release any resources. Called during cache shutdown
*/
void release();
}

View File

@ -0,0 +1,22 @@
/*
* 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.spi.support;
import org.hibernate.cache.spi.RegionFactory;
import org.hibernate.cache.spi.TimestampsRegion;
/**
* @author Steve Ebersole
*/
public class TimestampsRegionTemplate extends DirectAccessRegionTemplate implements TimestampsRegion {
public TimestampsRegionTemplate(
String name,
RegionFactory regionFactory,
StorageAccess storageAccess) {
super( name, regionFactory, storageAccess );
}
}

View File

@ -0,0 +1,34 @@
/*
* 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 intended for simplifying the worked needed to implement
* a caching provider. Centers around the concept of
* {@link org.hibernate.cache.spi.support.StorageAccess} and
* {@link org.hibernate.cache.spi.support.DomainDataStorageAccess}
* too implement most of the "grunt work" associated with the
* implementation.
*
* Most integrations would just:
*
* 1. implement a custom StorageAccess/DomainDataStorageAccess
* 2. implement a custom RegionFactoryTemplate, implementing specifically:
* a. `RegionFactoryTemplate#createDomainDataStorageAccess`
* b. `RegionFactoryTemplate#createQueryResultsRegionStorageAccess`
* c. `RegionFactoryTemplate#createTimestampsRegionStorageAccess`
*
* Voila.. functioning cache provider
*
* The preferred approach to "provide a integration" is through a custom
* {@link org.hibernate.boot.registry.selector.StrategyRegistrationProvider}
*
* Both `hibernate-testing` (`org.hibernate.testing.cache.CachingRegionFactory`)
* and `hibernate-jcache` (`org.hibernate.cache.jcache.internal.JCacheRegionFactory`)
* provide examples of using this support package to implement a caching
* provider.
*/
package org.hibernate.cache.spi.support;

View File

@ -13,7 +13,7 @@ import javax.persistence.GeneratedValue;
import org.hibernate.Transaction;
import org.hibernate.boot.MetadataBuilder;
import org.hibernate.boot.registry.classloading.internal.TcclLookupPrecedence;
import org.hibernate.cache.spi.TimestampsRegionAccessFactory;
import org.hibernate.cache.spi.TimestampsCacheFactory;
import org.hibernate.internal.log.DeprecationLogger;
import org.hibernate.jpa.JpaCompliance;
import org.hibernate.query.internal.ParameterMetadataImpl;
@ -1055,7 +1055,7 @@ public interface AvailableSettings extends org.hibernate.jpa.AvailableSettings {
String USE_QUERY_CACHE = "hibernate.cache.use_query_cache";
/**
* The {@link TimestampsRegionAccessFactory} implementation class.
* The {@link TimestampsCacheFactory} implementation class.
*/
String QUERY_CACHE_FACTORY = "hibernate.cache.query_cache_factory";

View File

@ -17,7 +17,7 @@ import org.hibernate.boot.SchemaAutoTooling;
import org.hibernate.boot.model.naming.Identifier;
import org.hibernate.boot.spi.SessionFactoryOptions;
import org.hibernate.cache.spi.RegionFactory;
import org.hibernate.cache.spi.TimestampsRegionAccessFactory;
import org.hibernate.cache.spi.TimestampsCacheFactory;
import org.hibernate.engine.transaction.jta.platform.spi.JtaPlatform;
import org.hibernate.hql.spi.QueryTranslatorFactory;
import org.hibernate.hql.spi.id.MultiTableBulkIdStrategy;
@ -34,6 +34,7 @@ import org.jboss.logging.Logger;
*
* @deprecated Use {@link org.hibernate.boot.spi.SessionFactoryOptions} instead.
*/
@SuppressWarnings("unused")
@Deprecated
public final class Settings {
private static final Logger LOG = Logger.getLogger( Settings.class );
@ -93,7 +94,7 @@ public final class Settings {
LOG.debugf( "Second-level cache: %s", enabledDisabled( sessionFactoryOptions.isSecondLevelCacheEnabled() ) );
LOG.debugf( "Second-level query cache: %s", enabledDisabled( sessionFactoryOptions.isQueryCacheEnabled() ) );
LOG.debugf( "Second-level query cache factory: %s", sessionFactoryOptions.getTimestampsRegionAccessFactory() );
LOG.debugf( "Second-level query cache factory: %s", sessionFactoryOptions.getTimestampsCacheFactory() );
LOG.debugf( "Second-level cache region prefix: %s", sessionFactoryOptions.getCacheRegionPrefix() );
LOG.debugf( "Optimize second-level cache for minimal puts: %s", enabledDisabled( sessionFactoryOptions.isMinimalPutsEnabled() ) );
LOG.debugf( "Structured second-level cache entries: %s", enabledDisabled( sessionFactoryOptions.isStructuredCacheEntriesEnabled() ) );
@ -227,8 +228,8 @@ public final class Settings {
return sessionFactoryOptions.isQueryCacheEnabled();
}
public TimestampsRegionAccessFactory getTimestampsRegionAccessFactory() {
return sessionFactoryOptions.getTimestampsRegionAccessFactory();
public TimestampsCacheFactory getTimestampsCacheFactory() {
return sessionFactoryOptions.getTimestampsCacheFactory();
}
public String getCacheRegionPrefix() {

View File

@ -663,7 +663,7 @@ public class ActionQueue {
afterTransactionProcesses.addSpaceToInvalidate( (String) s );
}
// Performance win: If we are processing an ExecutableList, this will only be called once
session.getFactory().getCache().getTimestampsRegionAccess().preInvalidate( spaces, session );
session.getFactory().getCache().getTimestampsCache().preInvalidate( spaces, session );
}
}
@ -992,7 +992,7 @@ public class ActionQueue {
}
if ( session.getFactory().getSessionFactoryOptions().isQueryCacheEnabled() ) {
session.getFactory().getCache().getTimestampsRegionAccess().invalidate(
session.getFactory().getCache().getTimestampsCache().invalidate(
querySpacesToInvalidate.toArray( new String[querySpacesToInvalidate.size()] ),
session
);

View File

@ -14,10 +14,10 @@ import org.hibernate.Cache;
import org.hibernate.HibernateException;
import org.hibernate.cache.cfg.spi.DomainDataRegionConfig;
import org.hibernate.cache.spi.QueryCache;
import org.hibernate.cache.spi.QueryResultRegionAccess;
import org.hibernate.cache.spi.QueryResultsCache;
import org.hibernate.cache.spi.Region;
import org.hibernate.cache.spi.RegionFactory;
import org.hibernate.cache.spi.TimestampsRegionAccess;
import org.hibernate.cache.spi.TimestampsCache;
import org.hibernate.cache.spi.UpdateTimestampsCache;
import org.hibernate.cache.spi.access.CollectionDataAccess;
import org.hibernate.cache.spi.access.EntityDataAccess;
@ -82,14 +82,14 @@ public interface CacheImplementor extends Service, Cache, Serializable {
*
* @since 5.3
*/
TimestampsRegionAccess getTimestampsRegionAccess();
TimestampsCache getTimestampsCache();
/**
* Access to the "default" region used to store query results when caching
* was requested but no region was explicitly named. Will return {@code null}
* if Hibernate is not configured for query result caching
*/
QueryResultRegionAccess getDefaultQueryResultsRegionAccess();
QueryResultsCache getDefaultQueryResultsCache();
/**
* Get query cache by <tt>region name</tt> or create a new one if none exist.
@ -98,7 +98,7 @@ public interface CacheImplementor extends Service, Cache, Serializable {
*
* Will return {@code null} if Hibernate is not configured for query result caching
*/
QueryResultRegionAccess getQueryResultsRegionAccess(String regionName);
QueryResultsCache getQueryResultsCache(String regionName);
/**
* Get the named QueryResultRegionAccess but not creating one if it
@ -109,13 +109,13 @@ public interface CacheImplementor extends Service, Cache, Serializable {
*
* @since 5.3
*/
QueryResultRegionAccess getQueryResultsRegionAccessStrictly(String regionName);
QueryResultsCache getQueryResultsCacheStrictly(String regionName);
/**
* Clean up the default query cache
*/
default void evictQueries() throws HibernateException {
QueryResultRegionAccess cache = getDefaultQueryResultsRegionAccess();
QueryResultsCache cache = getDefaultQueryResultsCache();
if ( cache != null ) {
cache.clear();
}
@ -185,39 +185,39 @@ public interface CacheImplementor extends Service, Cache, Serializable {
/**
* Get {@code UpdateTimestampsCache} instance managed by the {@code SessionFactory}.
*
* @deprecated Use {@link #getTimestampsRegionAccess} instead
* @deprecated Use {@link #getTimestampsCache} instead
*/
@Deprecated
default UpdateTimestampsCache getUpdateTimestampsCache() {
return getTimestampsRegionAccess();
return getTimestampsCache();
}
/**
* Get the default {@code QueryCache}.
*
* @deprecated Use {@link #getDefaultQueryResultsRegionAccess} instead.
* @deprecated Use {@link #getDefaultQueryResultsCache} instead.
*/
@Deprecated
default QueryCache getQueryCache() {
return getDefaultQueryResultsRegionAccess();
return getDefaultQueryResultsCache();
}
/**
* Get the default {@code QueryCache}.
*
* @deprecated Use {@link #getDefaultQueryResultsRegionAccess} instead.
* @deprecated Use {@link #getDefaultQueryResultsCache} instead.
*/
@Deprecated
default QueryCache getDefaultQueryCache() {
return getDefaultQueryResultsRegionAccess();
return getDefaultQueryResultsCache();
}
/**
* @deprecated Use {@link #getQueryResultsRegionAccess(String)} instead, but using unqualified name
* @deprecated Use {@link #getQueryResultsCache(String)} instead, but using unqualified name
*/
@Deprecated
default QueryCache getQueryCache(String regionName) throws HibernateException {
return getQueryResultsRegionAccess( unqualifyRegionName( regionName ) );
return getQueryResultsCache( unqualifyRegionName( regionName ) );
}

View File

@ -1066,7 +1066,7 @@ public interface CoreMessageLogger extends BasicLogger {
String unableToDetermineTransactionStatusAfterCommit();
@LogMessage(level = WARN)
@Message(value = "Unable to drop temporary id table after use [%s]", id = 314)
@Message(value = "Unable to evictData temporary id table after use [%s]", id = 314)
void unableToDropTemporaryIdTable(String message);
@LogMessage(level = ERROR)
@ -1738,7 +1738,7 @@ public interface CoreMessageLogger extends BasicLogger {
void executingImportScript(String scriptName);
@LogMessage(level = INFO)
@Message(value = "Starting delayed drop of schema as part of SessionFactory shut-down'", id = 477)
@Message(value = "Starting delayed evictData of schema as part of SessionFactory shut-down'", id = 477)
void startingDelayedSchemaDrop();
@LogMessage(level = ERROR)

View File

@ -33,7 +33,7 @@ import org.hibernate.StaleObjectStateException;
import org.hibernate.WrongClassException;
import org.hibernate.cache.spi.FilterKey;
import org.hibernate.cache.spi.QueryKey;
import org.hibernate.cache.spi.QueryResultRegionAccess;
import org.hibernate.cache.spi.QueryResultsCache;
import org.hibernate.cache.spi.access.EntityDataAccess;
import org.hibernate.cache.spi.entry.CacheEntry;
import org.hibernate.cache.spi.entry.ReferenceCacheEntryImpl;
@ -2512,7 +2512,7 @@ public abstract class Loader {
final Set<Serializable> querySpaces,
final Type[] resultTypes) {
QueryResultRegionAccess queryCache = factory.getCache().getQueryResultsRegionAccess( queryParameters.getCacheRegion() );
QueryResultsCache queryCache = factory.getCache().getQueryResultsCache( queryParameters.getCacheRegion() );
QueryKey key = generateQueryKey( session, queryParameters );
@ -2589,7 +2589,7 @@ public abstract class Loader {
final QueryParameters queryParameters,
final Set<Serializable> querySpaces,
final Type[] resultTypes,
final QueryResultRegionAccess queryCache,
final QueryResultsCache queryCache,
final QueryKey key) {
List result = null;
@ -2647,7 +2647,7 @@ public abstract class Loader {
final SharedSessionContractImplementor session,
final QueryParameters queryParameters,
final Type[] resultTypes,
final QueryResultRegionAccess queryCache,
final QueryResultsCache queryCache,
final QueryKey key,
final List result) {
if ( session.getCacheMode().isPutEnabled() ) {

View File

@ -21,7 +21,7 @@ import org.hibernate.LockOptions;
import org.hibernate.QueryException;
import org.hibernate.Session;
import org.hibernate.cache.spi.QueryKey;
import org.hibernate.cache.spi.QueryResultRegionAccess;
import org.hibernate.cache.spi.QueryResultsCache;
import org.hibernate.dialect.Dialect;
import org.hibernate.engine.spi.QueryParameters;
import org.hibernate.engine.spi.SessionFactoryImplementor;
@ -542,7 +542,7 @@ public class CustomLoader extends Loader {
final SharedSessionContractImplementor session,
final QueryParameters queryParameters,
final Type[] resultTypes,
final QueryResultRegionAccess queryCache,
final QueryResultsCache queryCache,
final QueryKey key,
final List result) {
super.putResultInQueryCache( session, queryParameters, this.resultTypes, queryCache, key, result );

View File

@ -168,7 +168,7 @@ public abstract class Constraint implements RelationalModel, Exportable, Seriali
final String tableName = getTable().getQualifiedName( dialect, defaultCatalog, defaultSchema );
return String.format(
Locale.ROOT,
"%s drop constraint %s",
"%s evictData constraint %s",
dialect.getAlterTableString( tableName ),
dialect.quote( getName() )
);

View File

@ -10,7 +10,7 @@ import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.atomic.AtomicLong;
import org.hibernate.cache.spi.QueryResultRegionAccess;
import org.hibernate.cache.spi.QueryResultsCache;
import org.hibernate.cache.spi.QueryResultsRegion;
import org.hibernate.cache.spi.Region;
import org.hibernate.engine.spi.SessionFactoryImplementor;
@ -599,8 +599,8 @@ public class StatisticsImpl implements StatisticsImplementor, Service {
return null;
}
final QueryResultRegionAccess regionAccess = sessionFactory.getCache()
.getQueryResultsRegionAccessStrictly( regionName );
final QueryResultsCache regionAccess = sessionFactory.getCache()
.getQueryResultsCacheStrictly( regionName );
if ( regionAccess == null ) {
return null;
}
@ -770,7 +770,7 @@ public class StatisticsImpl implements StatisticsImplementor, Service {
private CacheRegionStatisticsImpl getQueryRegionStats(String regionName) {
return l2CacheStatsMap.computeIfAbsent(
regionName,
s -> new CacheRegionStatisticsImpl( sessionFactory.getCache().getQueryResultsRegionAccess( regionName ).getRegion() )
s -> new CacheRegionStatisticsImpl( sessionFactory.getCache().getQueryResultsCache( regionName ).getRegion() )
);
}

View File

@ -1,48 +0,0 @@
/*
* 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();
}
}

View File

@ -1,25 +0,0 @@
/*
* 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 );
}
}

View File

@ -9,7 +9,6 @@ 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;
@ -24,14 +23,10 @@ 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.DomainDataStorageAccess;
import org.hibernate.cache.spi.support.RegionFactoryTemplate;
import org.hibernate.cache.spi.support.RegionNameQualifier;
import org.hibernate.cache.spi.support.SimpleTimestamper;
import org.hibernate.cache.spi.support.StorageAccess;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.jboss.logging.Logger;
@ -42,14 +37,12 @@ import static org.hibernate.cache.ehcache.ConfigSettings.EHCACHE_CONFIGURATION_R
* @author Steve Ebersole
* @author Alex Snaps
*/
public class EhcacheRegionFactory implements RegionFactory {
public class EhcacheRegionFactory extends RegionFactoryTemplate {
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 );
@ -63,51 +56,74 @@ public class EhcacheRegionFactory implements RegionFactory {
return cacheManager;
}
public SessionFactoryOptions getOptions() {
return options;
@Override
protected CacheKeysFactory getImplicitCacheKeysFactory() {
return cacheKeysFactory;
}
@Override
public boolean isMinimalPutsEnabledByDefault() {
return true;
protected DomainDataStorageAccess createDomainDataStorageAccess(
DomainDataRegionConfig regionConfig,
DomainDataRegionBuildingContext buildingContext) {
return new StorageAccessImpl(
getOrCreateCache( regionConfig.getRegionName(), buildingContext.getSessionFactory() )
);
}
@Override
public AccessType getDefaultAccessType() {
return AccessType.READ_WRITE;
protected StorageAccess createQueryResultsRegionStorageAccess(
String regionName,
SessionFactoryImplementor sessionFactory) {
return new StorageAccessImpl( getOrCreateCache( regionName, sessionFactory ) );
}
@Override
public long nextTimestamp() {
return SimpleTimestamper.next();
protected StorageAccess createTimestampsRegionStorageAccess(
String regionName,
SessionFactoryImplementor sessionFactory) {
return new StorageAccessImpl( getOrCreateCache( regionName, sessionFactory ) );
}
protected Cache getOrCreateCache(String unqualifiedRegionName, SessionFactoryImplementor sessionFactory) {
verifyStarted();
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 + "]" );
}
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Lifecycle
protected boolean isStarted() {
return super.isStarted() && cacheManager != null;
}
@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 );
}
}
protected void prepareForUse(SessionFactoryOptions settings, Map configValues) {
synchronized ( this ) {
this.cacheManager = resolveCacheManager( settings, configValues );
if ( this.cacheManager == null ) {
throw new CacheException( "Could not start Ehcache CacheManager" );
}
}
else {
SecondLevelCacheLogger.INSTANCE.attemptToStartAlreadyStartedCacheProvider();
}
}
private CacheManager getCacheManager(SessionFactoryOptions settings, Map properties) {
protected CacheManager resolveCacheManager(SessionFactoryOptions settings, Map properties) {
final Object explicitCacheManager = properties.get( ConfigSettings.CACHE_MANAGER );
if ( explicitCacheManager != null ) {
return useExplicitCacheManager( settings, explicitCacheManager );
@ -116,10 +132,6 @@ public class EhcacheRegionFactory implements RegionFactory {
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
@ -201,7 +213,7 @@ public class EhcacheRegionFactory implements RegionFactory {
throw new IllegalStateException( "Cannot load resource through a non-started EhcacheRegionFactory" );
}
return loadResource( configurationResourceName, options );
return loadResource( configurationResourceName, getOptions() );
}
private CacheManager useExplicitCacheManager(SessionFactoryOptions settings, Object setting) {
@ -227,96 +239,15 @@ public class EhcacheRegionFactory implements RegionFactory {
}
@Override
public void stop() {
if ( started.compareAndSet( true, false ) ) {
synchronized ( this ) {
releaseCacheManager();
cacheManager = null;
}
protected void releaseFromUse() {
try {
// 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();
}
else {
SecondLevelCacheLogger.INSTANCE.attemptToStopAlreadyStoppedCacheProvider();
finally {
cacheManager = null;
}
}
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;
}
}

View File

@ -1,36 +0,0 @@
/*
* 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;
}
}

View File

@ -11,9 +11,7 @@ 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;
@ -79,9 +77,9 @@ public class SingletonEhcacheRegionFactory extends EhcacheRegionFactory {
}
@Override
protected void releaseCacheManager() {
protected void releaseFromUse() {
if ( REFERENCE_COUNT.decrementAndGet() == 0 ) {
getCacheManager().shutdown();
super.releaseFromUse();
}
}
}

View File

@ -12,18 +12,22 @@ 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.hibernate.cache.spi.support.DomainDataStorageAccess;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.jboss.logging.Logger;
/**
* Implementation of StorageAccess for "talking to" Ehcache
*
* @author Steve Ebersole
*/
public class StorageAccessImpl implements StorageAccess {
public class StorageAccessImpl implements DomainDataStorageAccess {
private static final Logger LOG = Logger.getLogger( StorageAccessImpl.class );
private final Cache cache;
@SuppressWarnings("WeakerAccess")
public StorageAccessImpl(Cache cache) {
this.cache = cache;
}
@ -32,9 +36,13 @@ public class StorageAccessImpl implements StorageAccess {
return cache;
}
@Override
public boolean contains(Object key) {
return getCache().isKeyInCache( key );
}
@Override
public Object getFromCache(Object key) {
public Object getFromCache(Object key, SharedSessionContractImplementor session) {
try {
final Element element = getCache().get( key );
if ( element == null ) {
@ -57,7 +65,7 @@ public class StorageAccessImpl implements StorageAccess {
}
@Override
public void putIntoCache(Object key, Object value) {
public void putIntoCache(Object key, Object value, SharedSessionContractImplementor session) {
try {
final Element element = new Element( key, value );
getCache().put( element );
@ -77,7 +85,7 @@ public class StorageAccessImpl implements StorageAccess {
}
@Override
public void removeFromCache(Object key) {
public void evictData(Object key) {
try {
getCache().remove( key );
}
@ -96,7 +104,7 @@ public class StorageAccessImpl implements StorageAccess {
}
@Override
public void clearCache() {
public void evictData() {
try {
getCache().removeAll();
}

View File

@ -1,38 +0,0 @@
/*
* 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;
}
}

View File

@ -1,27 +0,0 @@
/*
* 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 javax.cache.Cache;
import org.hibernate.cache.spi.support.DomainDataStorageAccess;
/**
* DomainDataStorageAccess implementation wrapping a JCache {@link Cache} reference.
*
* @author Steve Ebersole
*/
public class DomainDataJCacheAccessImpl extends JCacheAccessImpl implements DomainDataStorageAccess {
public DomainDataJCacheAccessImpl(Cache underlyingCache) {
super( underlyingCache );
}
@Override
public void putFromLoad(Object key, Object value) {
putIntoCache( key, value );
}
}

View File

@ -1,47 +0,0 @@
/*
* 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 javax.cache.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.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,
JCacheRegionFactory regionFactory,
Cache underlyingCache,
CacheKeysFactory cacheKeysFactory,
DomainDataRegionBuildingContext buildingContext) {
super(
regionConfig,
regionFactory,
new DomainDataJCacheAccessImpl( underlyingCache ),
cacheKeysFactory,
buildingContext
);
}
/**
* Public override for testing use only
*/
@Override
public DomainDataJCacheAccessImpl getCacheStorageAccess() {
return (DomainDataJCacheAccessImpl) super.getCacheStorageAccess();
}
}

View File

@ -8,7 +8,8 @@ package org.hibernate.cache.jcache.internal;
import javax.cache.Cache;
import org.hibernate.cache.spi.support.StorageAccess;
import org.hibernate.cache.spi.support.DomainDataStorageAccess;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
/**
* StorageAccess implementation wrapping a JCache {@link Cache} reference.
@ -16,7 +17,7 @@ import org.hibernate.cache.spi.support.StorageAccess;
* @author Steve Ebersole
*/
@SuppressWarnings("unchecked")
public class JCacheAccessImpl implements StorageAccess {
public class JCacheAccessImpl implements DomainDataStorageAccess {
private final Cache underlyingCache;
public JCacheAccessImpl(Cache underlyingCache) {
@ -28,22 +29,37 @@ public class JCacheAccessImpl implements StorageAccess {
}
@Override
public Object getFromCache(Object key) {
public boolean contains(Object key) {
return underlyingCache.containsKey( key );
}
@Override
public Object getFromCache(Object key, SharedSessionContractImplementor session) {
return underlyingCache.get( key );
}
@Override
public void putIntoCache(Object key, Object value) {
public void putIntoCache(Object key, Object value, SharedSessionContractImplementor session) {
underlyingCache.put( key, value );
}
@Override
public void removeFromCache(Object key) {
public void removeFromCache(Object key, SharedSessionContractImplementor session) {
underlyingCache.remove( key );
}
@Override
public void clearCache() {
public void evictData(Object key) {
underlyingCache.remove( key );
}
@Override
public void clearCache(SharedSessionContractImplementor session) {
underlyingCache.clear();
}
@Override
public void evictData() {
underlyingCache.clear();
}

View File

@ -1,58 +0,0 @@
/*
* 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.jboss.logging.annotations.LogMessage;
import org.jboss.logging.annotations.Message;
import org.jboss.logging.annotations.MessageLogger;
import org.hibernate.cache.spi.Region;
import org.hibernate.cache.spi.SecondLevelCacheLogger;
import org.hibernate.internal.CoreMessageLogger;
import static org.jboss.logging.Logger.Level.ERROR;
import static org.jboss.logging.Logger.Level.WARN;
/**
* @author Alex Snaps
*/
@MessageLogger(projectCode = "HHH")
public interface JCacheMessageLogger extends CoreMessageLogger {
static final int NAMESPACE = 40000;
/**
* @deprecated (since 5.3) Use {@link SecondLevelCacheLogger#attemptToStartAlreadyStartedCacheProvider()}
*/
@LogMessage(level = WARN)
@Message(
value = "Attempt to restart an already started JCacheRegionFactory. Use sessionFactory.close() between " +
"repeated calls to buildSessionFactory. Using previously created JCacheRegionFactory.",
id = NAMESPACE + 1
)
@Deprecated
void attemptToRestartAlreadyStartedJCacheProvider();
/**
* @deprecated (since 5.3) Use {@link SecondLevelCacheLogger#attemptToStopAlreadyStoppedCacheProvider()}
*/
@LogMessage(level = WARN)
@Message(
value = "Attempt to restop an already stopped JCacheRegionFactory.",
id = NAMESPACE + 2
)
@Deprecated
void attemptToRestopAlreadyStoppedJCacheProvider();
@LogMessage(level = ERROR)
@Message(
value = "Cache: %s Key: %s Lockable: %s. A soft-locked cache entry was missing. This is either"
+ " out of balance lock/unlock sequences, or an eagerly evicting cache.",
id = NAMESPACE + 3
)
void missingLock(Region region, Object key, Object value);
}

View File

@ -9,7 +9,6 @@ package org.hibernate.cache.jcache.internal;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.Map;
import java.util.concurrent.atomic.AtomicBoolean;
import javax.cache.Cache;
import javax.cache.CacheManager;
import javax.cache.Caching;
@ -23,34 +22,21 @@ import org.hibernate.cache.cfg.spi.DomainDataRegionConfig;
import org.hibernate.cache.internal.DefaultCacheKeysFactory;
import org.hibernate.cache.jcache.ConfigSettings;
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.DomainDataStorageAccess;
import org.hibernate.cache.spi.support.RegionFactoryTemplate;
import org.hibernate.cache.spi.support.RegionNameQualifier;
import org.hibernate.cache.spi.support.SimpleTimestamper;
import org.hibernate.cache.spi.support.StorageAccess;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.jboss.logging.Logger;
/**
* @author Alex Snaps
*/
public class JCacheRegionFactory implements RegionFactory {
private static final JCacheMessageLogger LOG = Logger.getMessageLogger(
JCacheMessageLogger.class,
JCacheRegionFactory.class.getName()
);
private final AtomicBoolean started = new AtomicBoolean( false );
public class JCacheRegionFactory extends RegionFactoryTemplate {
private final CacheKeysFactory cacheKeysFactory;
private volatile CacheManager cacheManager;
private SessionFactoryOptions options;
@SuppressWarnings("unused")
public JCacheRegionFactory() {
this( DefaultCacheKeysFactory.INSTANCE );
}
@ -59,51 +45,84 @@ public class JCacheRegionFactory implements RegionFactory {
this.cacheKeysFactory = cacheKeysFactory;
}
@SuppressWarnings("unused")
public CacheManager getCacheManager() {
return cacheManager;
}
@Override
public boolean isMinimalPutsEnabledByDefault() {
return true;
protected CacheKeysFactory getImplicitCacheKeysFactory() {
return cacheKeysFactory;
}
@Override
public AccessType getDefaultAccessType() {
return AccessType.READ_WRITE;
protected DomainDataStorageAccess createDomainDataStorageAccess(
DomainDataRegionConfig regionConfig,
DomainDataRegionBuildingContext buildingContext) {
return new JCacheAccessImpl(
getOrCreateCache( regionConfig.getRegionName(), buildingContext.getSessionFactory() )
);
}
@Override
public long nextTimestamp() {
return SimpleTimestamper.next();
}
@SuppressWarnings("WeakerAccess")
protected Cache<Object, Object> getOrCreateCache(String unqualifiedRegionName, SessionFactoryImplementor sessionFactory) {
verifyStarted();
assert !RegionNameQualifier.INSTANCE.isQualified( unqualifiedRegionName, sessionFactory.getSessionFactoryOptions() );
@Override
public long getTimeout() {
return SimpleTimestamper.timeOut();
}
final String qualifiedRegionName = RegionNameQualifier.INSTANCE.qualify(
unqualifiedRegionName,
sessionFactory.getSessionFactoryOptions()
);
@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 );
}
}
}
final Cache<Object, Object> cache = cacheManager.getCache( qualifiedRegionName );
if ( cache == null ) {
return createCache( qualifiedRegionName );
}
else {
SecondLevelCacheLogger.INSTANCE.attemptToStartAlreadyStartedCacheProvider();
return cache;
}
@SuppressWarnings("WeakerAccess")
protected Cache<Object, Object> createCache(String regionName) {
throw new CacheException( "On-the-fly creation of JCache Cache objects is not supported [" + regionName + "]" );
}
@Override
protected StorageAccess createQueryResultsRegionStorageAccess(
String regionName,
SessionFactoryImplementor sessionFactory) {
return new JCacheAccessImpl(
getOrCreateCache( regionName, sessionFactory )
);
}
@Override
protected StorageAccess createTimestampsRegionStorageAccess(
String regionName,
SessionFactoryImplementor sessionFactory) {
return new JCacheAccessImpl(
getOrCreateCache( regionName, sessionFactory )
);
}
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Lifecycle
@Override
protected boolean isStarted() {
return super.isStarted() && cacheManager != null;
}
@Override
protected void prepareForUse(SessionFactoryOptions settings, Map configValues) {
this.cacheManager = resolveCacheManager( settings, configValues );
if ( this.cacheManager == null ) {
throw new CacheException( "Could not locate/create CacheManager" );
}
}
protected CacheManager getCacheManager(SessionFactoryOptions settings, Map properties) {
@SuppressWarnings("WeakerAccess")
protected CacheManager resolveCacheManager(SessionFactoryOptions settings, Map properties) {
final Object explicitCacheManager = properties.get( ConfigSettings.CACHE_MANAGER );
if ( explicitCacheManager != null ) {
return useExplicitCacheManager( settings, explicitCacheManager );
@ -129,6 +148,11 @@ public class JCacheRegionFactory implements RegionFactory {
return cacheManager;
}
private String getProp(Map properties, String prop) {
return properties != null ? (String) properties.get( prop ) : null;
}
@SuppressWarnings("WeakerAccess")
protected CachingProvider getCachingProvider(final Map properties){
final CachingProvider cachingProvider;
final String provider = getProp( properties, ConfigSettings.PROVIDER );
@ -141,6 +165,7 @@ public class JCacheRegionFactory implements RegionFactory {
return cachingProvider;
}
@SuppressWarnings("unchecked")
private CacheManager useExplicitCacheManager(SessionFactoryOptions settings, Object setting) {
if ( setting instanceof CacheManager ) {
return (CacheManager) setting;
@ -164,92 +189,15 @@ public class JCacheRegionFactory implements RegionFactory {
}
@Override
public void stop() {
if ( started.compareAndSet( true, false ) ) {
synchronized ( this ) {
// 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.close();
cacheManager = null;
}
protected void releaseFromUse() {
try {
// 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.close();
}
else {
LOG.attemptToRestopAlreadyStoppedJCacheProvider();
finally {
cacheManager = null;
}
}
@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<Object, Object> getOrCreateCache(String unqualifiedRegionName, SessionFactoryImplementor sessionFactory) {
checkStatus();
assert !RegionNameQualifier.INSTANCE.isQualified( unqualifiedRegionName, sessionFactory.getSessionFactoryOptions() );
final String qualifiedRegionName = RegionNameQualifier.INSTANCE.qualify(
unqualifiedRegionName,
sessionFactory.getSessionFactoryOptions()
);
final Cache<Object, Object> cache = cacheManager.getCache( qualifiedRegionName );
if ( cache == null ) {
return createCache( qualifiedRegionName );
}
return cache;
}
protected Cache<Object, Object> 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;
}
}

View File

@ -1,35 +0,0 @@
/*
* 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 javax.cache.Cache;
import org.hibernate.cache.spi.QueryResultsRegion;
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 JCacheAccessImpl cacheAccess;
public QueryResultsRegionImpl(
String name,
JCacheRegionFactory regionFactory,
Cache cache) {
super( name, regionFactory );
this.cacheAccess = new JCacheAccessImpl( cache );
}
@Override
public StorageAccess getStorageAccess() {
return cacheAccess;
}
}

View File

@ -1,37 +0,0 @@
/*
* 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 javax.cache.Cache;
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 JCacheAccessImpl cacheAccess;
public TimestampsRegionImpl(
String regionName,
JCacheRegionFactory regionFactory,
Cache cache) {
super( regionName, regionFactory );
this.cacheAccess = new JCacheAccessImpl( cache );
}
@Override
public StorageAccess getStorageAccess() {
return cacheAccess;
}
}

View File

@ -6,13 +6,10 @@
*/
package org.hibernate.jcache.test;
import org.hibernate.cache.jcache.internal.DomainDataRegionImpl;
import org.hibernate.cache.spi.Region;
import org.hibernate.cache.spi.access.AccessType;
import org.hibernate.cache.spi.access.CollectionDataAccess;
import org.hibernate.cache.spi.access.EntityDataAccess;
import org.hibernate.jcache.test.BaseFunctionalTest;
import org.hibernate.jcache.test.TestHelper;
import org.hibernate.cache.spi.support.DomainDataRegionTemplate;
import org.hibernate.jcache.test.domain.Event;
import org.hibernate.jcache.test.domain.Item;
import org.hibernate.jcache.test.domain.VersionedItem;
@ -36,7 +33,7 @@ public class DomainDataRegionTest extends BaseFunctionalTest {
@Test
public void testBasicUsage() {
final Region region = sessionFactory().getCache().getRegion( TestHelper.entityRegionNames[0] );
final DomainDataRegionImpl domainDataRegion = assertTyping( DomainDataRegionImpl.class, region );
final DomainDataRegionTemplate domainDataRegion = assertTyping( DomainDataRegionTemplate.class, region );
// see if we can get access to all of the access objects we think should be defined in this region

View File

@ -14,11 +14,10 @@ import org.hibernate.annotations.Cache;
import org.hibernate.annotations.CacheConcurrencyStrategy;
import org.hibernate.boot.Metadata;
import org.hibernate.boot.MetadataSources;
import org.hibernate.cache.jcache.internal.DomainDataRegionImpl;
import org.hibernate.cache.spi.access.SoftLock;
import org.hibernate.cache.spi.support.DomainDataRegionTemplate;
import org.hibernate.cfg.AvailableSettings;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.jcache.test.TestHelper;
import org.hibernate.service.ServiceRegistry;
import org.hibernate.testing.junit4.BaseUnitTestCase;
@ -194,17 +193,23 @@ public class InsertedDataTest extends BaseUnitTestCase {
);
final DomainDataRegionImpl region = (DomainDataRegionImpl) sessionFactory().getCache().getRegion( "item" );
final Object fromCache = region.getCacheStorageAccess().getFromCache(
region.getEffectiveKeysFactory().createEntityKey(
1L,
sessionFactory().getMetamodel().entityPersister( CacheableItem.class ),
sessionFactory(),
null
)
inTransaction(
sessionFactory,
s -> {
final DomainDataRegionTemplate region = (DomainDataRegionTemplate) sessionFactory().getCache().getRegion( "item" );
final Object fromCache = region.getCacheStorageAccess().getFromCache(
region.getEffectiveKeysFactory().createEntityKey(
1L,
sessionFactory().getMetamodel().entityPersister( CacheableItem.class ),
sessionFactory(),
null
),
s
);
assertNotNull( fromCache );
ExtraAssertions.assertTyping( SoftLock.class, fromCache );
}
);
assertNotNull( fromCache );
ExtraAssertions.assertTyping( SoftLock.class, fromCache );
inTransaction(
sessionFactory,

View File

@ -11,10 +11,9 @@ import javax.cache.CacheManager;
import org.hibernate.cache.CacheException;
import org.hibernate.cache.jcache.JCacheHelper;
import org.hibernate.cache.jcache.internal.DomainDataJCacheAccessImpl;
import org.hibernate.cache.jcache.internal.DomainDataRegionImpl;
import org.hibernate.cache.jcache.internal.JCacheRegionFactory;
import org.hibernate.cache.jcache.internal.JCacheAccessImpl;
import org.hibernate.cache.spi.Region;
import org.hibernate.cache.spi.support.DomainDataRegionTemplate;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.service.spi.ServiceException;
@ -27,6 +26,7 @@ import static org.hamcrest.CoreMatchers.equalTo;
import static org.hamcrest.CoreMatchers.nullValue;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hibernate.testing.junit4.ExtraAssertions.assertTyping;
import static org.hibernate.testing.transaction.TransactionUtil2.inSession;
import static org.junit.Assert.fail;
/**
@ -71,22 +71,27 @@ public class StorageAccessTests extends BaseUnitTestCase {
public void testBasicStorageAccessUse() {
try (final SessionFactoryImplementor sessionFactory = TestHelper.buildStandardSessionFactory( true ) ) {
final Region region = sessionFactory.getCache().getRegion( TestHelper.entityRegionNames[0] );
final DomainDataRegionImpl jcacheRegion = (DomainDataRegionImpl) region;
final DomainDataJCacheAccessImpl access = jcacheRegion.getCacheStorageAccess();
final JCacheAccessImpl access = (JCacheAccessImpl) ( (DomainDataRegionTemplate) region ).getCacheStorageAccess();
final Cache jcache = access.getUnderlyingCache();
access.putIntoCache( "key", "value" );
assertThat( jcache.get( "key" ), equalTo( "value" ) );
assertThat( access.getFromCache( "key" ), equalTo( "value" ) );
inSession(
sessionFactory,
s -> {
access.putIntoCache( "key", "value", s );
assertThat( jcache.get( "key" ), equalTo( "value" ) );
assertThat( access.getFromCache( "key", s ), equalTo( "value" ) );
access.removeFromCache( "key" );
assertThat( jcache.get( "key" ), nullValue() );
assertThat( access.getFromCache( "key" ), nullValue() );
access.removeFromCache( "key", s );
assertThat( jcache.get( "key" ), nullValue() );
assertThat( access.getFromCache( "key", s ), nullValue() );
}
);
}
}
@Test
@SuppressWarnings({"EmptyTryBlock", "unused"})
public void testCachesReleasedOnSessionFactoryClose() {
try (SessionFactoryImplementor sessionFactory = TestHelper.buildStandardSessionFactory( true ) ) {
}

View File

@ -11,9 +11,10 @@ import java.util.List;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.hibernate.cache.jcache.internal.DomainDataRegionImpl;
import org.hibernate.cache.spi.access.SoftLock;
import org.hibernate.cache.spi.support.AbstractReadWriteAccess;
import org.hibernate.cache.spi.support.DomainDataRegionTemplate;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.jcache.test.BaseFunctionalTest;
import org.hibernate.jcache.test.domain.Event;
import org.hibernate.jcache.test.domain.EventManager;
@ -72,7 +73,7 @@ public class HibernateCacheTest extends BaseFunctionalTest {
assertThat( slcs.getPutCount(), equalTo( 2L ) );
assertTrue( sessionFactory().getCache().containsEntity( Item.class, i.getId() ) );
final DomainDataRegionImpl region = (DomainDataRegionImpl) sessionFactory().getMetamodel()
final DomainDataRegionTemplate region = (DomainDataRegionTemplate) sessionFactory().getMetamodel()
.entityPersister( Item.class )
.getCacheAccessStrategy()
.getRegion();
@ -82,7 +83,8 @@ public class HibernateCacheTest extends BaseFunctionalTest {
sessionFactory().getMetamodel().entityPersister( Item.class ),
sessionFactory(),
null
)
),
(SharedSessionContractImplementor) s
);
assertNotNull( fromCache );
ExtraAssertions.assertTyping( AbstractReadWriteAccess.Item.class, fromCache );
@ -167,7 +169,7 @@ public class HibernateCacheTest extends BaseFunctionalTest {
// assertThat( initialVersion, equalTo( cachedVersionValue ) );
// }
final DomainDataRegionImpl region = (DomainDataRegionImpl) sessionFactory().getMetamodel()
final DomainDataRegionTemplate region = (DomainDataRegionTemplate) sessionFactory().getMetamodel()
.entityPersister( Item.class )
.getCacheAccessStrategy()
.getRegion();
@ -177,7 +179,8 @@ public class HibernateCacheTest extends BaseFunctionalTest {
sessionFactory().getMetamodel().entityPersister( Item.class ),
sessionFactory(),
null
)
),
(SharedSessionContractImplementor) s
);
assertTrue(
fromCache == null || fromCache instanceof SoftLock

View File

@ -1,30 +0,0 @@
/*
* 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.cache;
import org.hibernate.cache.CacheException;
import org.hibernate.cache.spi.Region;
/**
* @author Steve Ebersole
*/
public abstract class AbstractRegion implements Region {
private final String name;
public AbstractRegion(String name) {
this.name = name;
}
@Override
public String getName() {
return name;
}
@Override
public void destroy() throws CacheException {
}
}

View File

@ -10,17 +10,13 @@ import java.util.Map;
import java.util.Properties;
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.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.TimestampsRegion;
import org.hibernate.cache.spi.access.AccessType;
import org.hibernate.cache.spi.support.RegionNameQualifier;
import org.hibernate.cache.spi.support.RegionFactoryTemplate;
import org.hibernate.cache.spi.support.StorageAccess;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.jboss.logging.Logger;
@ -29,16 +25,12 @@ import org.jboss.logging.Logger;
* @author Strong Liu
* @author Steve Ebersole
*/
public class CachingRegionFactory implements RegionFactory {
public class CachingRegionFactory extends RegionFactoryTemplate {
private static final Logger LOG = Logger.getLogger( CachingRegionFactory.class.getName() );
public static String DEFAULT_ACCESSTYPE = "DefaultAccessType";
private final CacheKeysFactory cacheKeysFactory;
private Properties properties;
private SessionFactoryOptions options;
public CachingRegionFactory() {
this( DefaultCacheKeysFactory.INSTANCE, null );
}
@ -54,70 +46,38 @@ public class CachingRegionFactory implements RegionFactory {
public CachingRegionFactory(CacheKeysFactory cacheKeysFactory, Properties properties) {
LOG.warn( "org.hibernate.testing.cache.CachingRegionFactory should be only used for testing." );
this.cacheKeysFactory = cacheKeysFactory;
this.properties = properties;
}
public CacheKeysFactory getCacheKeysFactory() {
return cacheKeysFactory;
}
@Override
public void start(SessionFactoryOptions settings, Map configValues) throws CacheException {
options = settings;
}
@Override
public void stop() {
}
@Override
public boolean isMinimalPutsEnabledByDefault() {
return false;
}
@Override
public AccessType getDefaultAccessType() {
if ( properties != null && properties.get( DEFAULT_ACCESSTYPE ) != null ) {
return AccessType.fromExternalName( properties.getProperty( DEFAULT_ACCESSTYPE ) );
}
return AccessType.READ_WRITE;
}
@Override
public String qualify(String regionName) {
return RegionNameQualifier.INSTANCE.qualify( regionName, options );
}
@Override
public long nextTimestamp() {
// return System.currentTimeMillis();
return Timestamper.next();
}
@Override
public long getTimeout() {
return Timestamper.ONE_MS * 60000;
protected void prepareForUse(SessionFactoryOptions settings, Map configValues) {
}
@Override
public DomainDataRegion buildDomainDataRegion(
DomainDataRegionConfig regionConfig,
DomainDataRegionBuildingContext buildingContext) {
return new DomainDataRegionImpl( regionConfig, this, cacheKeysFactory, buildingContext );
DomainDataRegionConfig regionConfig, DomainDataRegionBuildingContext buildingContext) {
return new DomainDataRegionImpl(
regionConfig,
this,
cacheKeysFactory,
buildingContext
);
}
@Override
public QueryResultsRegion buildQueryResultsRegion(
protected StorageAccess createQueryResultsRegionStorageAccess(
String regionName,
SessionFactoryImplementor sessionFactory) {
return new QueryResultsRegionImpl( regionName, this );
return new MapStorageAccessImpl();
}
@Override
public TimestampsRegion buildTimestampsRegion(
protected StorageAccess createTimestampsRegionStorageAccess(
String regionName,
SessionFactoryImplementor sessionFactory) {
return new TimestampsRegionImpl( regionName, this );
return new MapStorageAccessImpl();
}
@Override
protected void releaseFromUse() {
}
}

View File

@ -30,7 +30,7 @@ public class DomainDataRegionImpl extends DomainDataRegionTemplate {
super(
regionConfig,
regionFactory,
new DomainDataStorageAccessImpl(),
new MapStorageAccessImpl(),
defaultKeysFactory,
buildingContext
);

View File

@ -1,19 +0,0 @@
/*
* 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.cache;
import org.hibernate.cache.spi.support.DomainDataStorageAccess;
/**
* @author Steve Ebersole
*/
public class DomainDataStorageAccessImpl extends StorageAccessImpl implements DomainDataStorageAccess {
@Override
public void putFromLoad(Object key, Object value) {
getOrMakeDataMap().put( key, value );
}
}

View File

@ -33,7 +33,7 @@ public class EntityTransactionalAccess extends AbstractEntityDataAccess {
Object key,
Object value,
Object version) {
addToCache( key, value );
getStorageAccess().putIntoCache( key, value, session );
return true;
}
@ -53,7 +53,7 @@ public class EntityTransactionalAccess extends AbstractEntityDataAccess {
Object value,
Object currentVersion,
Object previousVersion) {
addToCache( key, value );
getStorageAccess().putIntoCache( key, value, session );
return true;
}

View File

@ -9,18 +9,24 @@ package org.hibernate.testing.cache;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import org.hibernate.cache.spi.support.StorageAccess;
import org.hibernate.cache.spi.support.DomainDataStorageAccess;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
/**
* StorageAccess impl wrapping a simple data Map (ConcurrentMap)
*
* @author Steve Ebersole
*/
public class StorageAccessImpl implements StorageAccess {
public class MapStorageAccessImpl implements DomainDataStorageAccess {
private ConcurrentMap data;
@Override
public Object getFromCache(Object key) {
public boolean contains(Object key) {
return data != null && data.containsKey( key );
}
@Override
public Object getFromCache(Object key, SharedSessionContractImplementor session) {
if ( data == null ) {
return null;
}
@ -29,7 +35,7 @@ public class StorageAccessImpl implements StorageAccess {
@Override
@SuppressWarnings("unchecked")
public void putIntoCache(Object key, Object value) {
public void putIntoCache(Object key, Object value, SharedSessionContractImplementor session) {
getOrMakeDataMap().put( key, value );
}
@ -42,7 +48,7 @@ public class StorageAccessImpl implements StorageAccess {
}
@Override
public void removeFromCache(Object key) {
public void removeFromCache(Object key, SharedSessionContractImplementor session) {
if ( data == null ) {
return;
}
@ -51,7 +57,7 @@ public class StorageAccessImpl implements StorageAccess {
}
@Override
public void clearCache() {
public void clearCache(SharedSessionContractImplementor session) {
if ( data == null ) {
return;
}
@ -59,9 +65,25 @@ public class StorageAccessImpl implements StorageAccess {
data.clear();
}
@Override
public void evictData() {
if ( data != null ) {
data.clear();
}
}
@Override
public void evictData(Object key) {
if ( data != null ) {
data.remove( key );
}
}
@Override
public void release() {
clearCache();
data = null;
if ( data != null ) {
data.clear();
data = null;
}
}
}

View File

@ -1,30 +0,0 @@
/*
* 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.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 Steve Ebersole
*/
public class QueryResultsRegionImpl extends DirectAccessRegionTemplate implements QueryResultsRegion {
private final StorageAccessImpl storageAccess = new StorageAccessImpl();
public QueryResultsRegionImpl(
String name,
RegionFactory regionFactory) {
super( name, regionFactory );
}
@Override
public StorageAccess getStorageAccess() {
return storageAccess;
}
}

View File

@ -6,9 +6,7 @@
*/
package org.hibernate.testing.cache;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import org.hibernate.boot.registry.selector.SimpleStrategyRegistrationImpl;
import org.hibernate.boot.registry.selector.StrategyRegistration;

View File

@ -1,41 +0,0 @@
/*
* 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.cache;
import java.util.concurrent.atomic.AtomicLong;
/**
* Generates increasing identifiers (in a single VM only). Not valid across multiple VMs. Identifiers are not
* necessarily strictly increasing, but usually are.
* <p/>
* Core while loop implemented by Alex Snaps - EHCache project - under ASL 2.0
*
* @author Hibernate team
* @author Alex Snaps
*/
public final class Timestamper {
private static final int BIN_DIGITS = 12;
public static final short ONE_MS = 1 << BIN_DIGITS;
private static final AtomicLong VALUE = new AtomicLong();
public static long next() {
while ( true ) {
long base = System.currentTimeMillis() << BIN_DIGITS;
long maxValue = base + ONE_MS - 1;
for ( long current = VALUE.get(), update = Math.max( base, current + 1 ); update < maxValue;
current = VALUE.get(), update = Math.max( base, current + 1 ) ) {
if ( VALUE.compareAndSet( current, update ) ) {
return update;
}
}
}
}
private Timestamper() {
}
}

View File

@ -1,30 +0,0 @@
/*
* 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.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;
/**
* @author Steve Ebersole
*/
public class TimestampsRegionImpl extends DirectAccessRegionTemplate implements TimestampsRegion {
private final StorageAccessImpl storageAccess = new StorageAccessImpl();
public TimestampsRegionImpl(
String name,
RegionFactory regionFactory) {
super( name, regionFactory );
}
@Override
public StorageAccess getStorageAccess() {
return storageAccess;
}
}