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:
parent
94e8ba7ba5
commit
b8674563d2
|
@ -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.
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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 );
|
|
@ -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 );
|
||||
}
|
||||
}
|
|
@ -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() {
|
|
@ -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 );
|
131
hibernate-core/src/main/java/org/hibernate/cache/spi/AbstractRegionFactory.java
vendored
Normal file
131
hibernate-core/src/main/java/org/hibernate/cache/spi/AbstractRegionFactory.java
vendored
Normal 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();
|
||||
}
|
||||
}
|
|
@ -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 ) );
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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
|
||||
*/
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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.
|
||||
*/
|
|
@ -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();
|
||||
|
||||
/**
|
||||
|
|
|
@ -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,
|
|
@ -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);
|
||||
}
|
|
@ -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
|
||||
|
|
|
@ -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;
|
|
@ -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>
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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 );
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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 );
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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 );
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
22
hibernate-core/src/main/java/org/hibernate/cache/spi/support/QueryResultsRegionTemplate.java
vendored
Normal file
22
hibernate-core/src/main/java/org/hibernate/cache/spi/support/QueryResultsRegionTemplate.java
vendored
Normal 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 );
|
||||
}
|
||||
}
|
77
hibernate-core/src/main/java/org/hibernate/cache/spi/support/RegionFactoryTemplate.java
vendored
Normal file
77
hibernate-core/src/main/java/org/hibernate/cache/spi/support/RegionFactoryTemplate.java
vendored
Normal 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);
|
||||
}
|
|
@ -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();
|
||||
|
||||
}
|
||||
|
|
22
hibernate-core/src/main/java/org/hibernate/cache/spi/support/TimestampsRegionTemplate.java
vendored
Normal file
22
hibernate-core/src/main/java/org/hibernate/cache/spi/support/TimestampsRegionTemplate.java
vendored
Normal 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 );
|
||||
}
|
||||
}
|
34
hibernate-core/src/main/java/org/hibernate/cache/spi/support/package-info.java
vendored
Normal file
34
hibernate-core/src/main/java/org/hibernate/cache/spi/support/package-info.java
vendored
Normal 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;
|
|
@ -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";
|
||||
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -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
|
||||
);
|
||||
|
|
|
@ -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 ) );
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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() ) {
|
||||
|
|
|
@ -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 );
|
||||
|
|
|
@ -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() )
|
||||
);
|
||||
|
|
|
@ -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() )
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
|
@ -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 );
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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 );
|
||||
}
|
||||
}
|
|
@ -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();
|
||||
}
|
||||
}
|
|
@ -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();
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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 ) ) {
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 {
|
||||
}
|
||||
}
|
|
@ -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() {
|
||||
}
|
||||
}
|
||||
|
|
|
@ -30,7 +30,7 @@ public class DomainDataRegionImpl extends DomainDataRegionTemplate {
|
|||
super(
|
||||
regionConfig,
|
||||
regionFactory,
|
||||
new DomainDataStorageAccessImpl(),
|
||||
new MapStorageAccessImpl(),
|
||||
defaultKeysFactory,
|
||||
buildingContext
|
||||
);
|
||||
|
|
|
@ -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 );
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
|
|
|
@ -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() {
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue