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

HHH-12323 - Update Statistics API and SPI based on changes to 2nd level caching changes

- initial work on migrating hibernate-jcache to new SPIs including a more template-style approach to writing a RegionFactory (o.h.cache.spi.support)
This commit is contained in:
Steve Ebersole 2018-03-16 08:54:03 -05:00
parent f432ecea68
commit 638ebf01df
83 changed files with 1335 additions and 1993 deletions

View File

@ -525,7 +525,7 @@ To use the `JCacheRegionFactory`, you need to specify the following configuratio
----
<property
name="hibernate.cache.region.factory_class"
value="org.hibernate.cache.jcache.JCacheRegionFactory"/>
value="jcache"/>
----
====

View File

@ -74,6 +74,7 @@ public EnabledCaching(SessionFactoryImplementor sessionFactory) {
this.sessionFactory = sessionFactory;
this.regionFactory = getSessionFactory().getSessionFactoryOptions().getServiceRegistry().getService( RegionFactory.class );
this.regionFactory.start( sessionFactory.getSessionFactoryOptions(), sessionFactory.getProperties() );
if ( getSessionFactory().getSessionFactoryOptions().isQueryCacheEnabled() ) {
final TimestampsRegion timestampsRegion = regionFactory.buildTimestampsRegion(

View File

@ -47,6 +47,11 @@ public void start(SessionFactoryOptions settings, Map configValues) throws Cache
public void stop() {
}
@Override
public String qualify(String regionName) {
return regionName;
}
@Override
public boolean isMinimalPutsEnabledByDefault() {
return false;
@ -59,7 +64,7 @@ public AccessType getDefaultAccessType() {
@Override
public long nextTimestamp() {
return System.currentTimeMillis() / 100;
return System.currentTimeMillis();
}
@Override

View File

@ -93,7 +93,7 @@ public boolean put(
try {
session.getEventListenerManager().cachePutStart();
cacheRegion.getAccess().addToCache( key, cacheItem );
cacheRegion.getStorageAccess().putIntoCache( key, cacheItem );
}
finally {
session.getEventListenerManager().cachePutEnd();
@ -189,7 +189,7 @@ private CacheItem getCachedData(QueryKey key, SharedSessionContractImplementor s
CacheItem cachedItem = null;
try {
session.getEventListenerManager().cacheGetStart();
cachedItem = (CacheItem) cacheRegion.getAccess().getFromCache( key );
cachedItem = (CacheItem) cacheRegion.getStorageAccess().getFromCache( key );
}
finally {
session.getEventListenerManager().cacheGetEnd( cachedItem != null );
@ -288,7 +288,7 @@ public String toString() {
@Override
public void clear() throws CacheException {
cacheRegion.getAccess().clearCache();
cacheRegion.getStorageAccess().clearCache();
}
public static class CacheItem implements Serializable {

View File

@ -57,7 +57,7 @@ public void preInvalidate(
//put() has nowait semantics, is this really appropriate?
//note that it needs to be async replication, never local or sync
timestampsRegion.getAccess().addToCache( space, ts );
timestampsRegion.getStorageAccess().putIntoCache( space, ts );
}
finally {
session.getEventListenerManager().cachePutEnd();
@ -84,7 +84,7 @@ public void invalidate(
try {
session.getEventListenerManager().cachePutStart();
timestampsRegion.getAccess().addToCache( space, ts );
timestampsRegion.getStorageAccess().putIntoCache( space, ts );
}
finally {
session.getEventListenerManager().cachePutEnd();
@ -135,7 +135,7 @@ private Long getLastUpdateTimestampForSpace(Serializable space, SharedSessionCon
Long ts = null;
try {
session.getEventListenerManager().cacheGetStart();
ts = (Long) timestampsRegion.getAccess().getFromCache( space );
ts = (Long) timestampsRegion.getStorageAccess().getFromCache( space );
}
finally {
session.getEventListenerManager().cacheGetEnd( ts != null );

View File

@ -6,6 +6,8 @@
*/
package org.hibernate.cache.spi;
import org.hibernate.cache.spi.support.StorageAccess;
/**
* Specialized Region whose data is accessed directly - not requiring
* key wrapping, e.g.
@ -13,30 +15,5 @@
* @author Steve Ebersole
*/
public interface DirectAccessRegion extends Region {
interface DataAccess {
Object getFromCache(Object key);
void addToCache(Object key, Object value);
void removeFromCache(Object key);
void clearCache();
}
DataAccess getAccess();
// Object get(Object key, SharedSessionContractImplementor session);
// void put(Object key, Object value, SharedSessionContractImplementor session);
//
// /**
// * Forcibly evict an item from the cache immediately without regard for transaction
// * isolation. This behavior is exactly Hibernate legacy behavior, but it is also required
// * by JPA - so we cannot remove it.
// *
// * @param key The key of the item to remove
// */
// void evict(Object key);
//
// /**
// * Forcibly evict all items from the cache immediately without regard for transaction
// * isolation. This behavior is exactly Hibernate legacy behavior, but it is also required
// * by JPA - so we cannot remove it.
// */
// void evictAll();
StorageAccess getStorageAccess();
}

View File

@ -36,7 +36,7 @@ public interface QueryResultRegionAccess extends QueryCache {
*/
@Override
default void clear() throws CacheException {
getRegion().getAccess().clearCache();
getRegion().getStorageAccess().clearCache();
}
/**

View File

@ -13,8 +13,4 @@
* @author Steve Ebersole
*/
public interface QueryResultsRegion extends DirectAccessRegion {
@Override
default void clear() {
getAccess().clearCache();
}
}

View File

@ -59,7 +59,11 @@ public interface RegionFactory extends Service, Stoppable {
*/
AccessType getDefaultAccessType();
CacheTransactionSynchronization createTransactionContext(SharedSessionContractImplementor session);
String qualify(String regionName);
default CacheTransactionSynchronization createTransactionContext(SharedSessionContractImplementor session) {
return new StandardCacheTransactionSynchronization( this );
}
/**
* Generate a timestamp. This value is generally used for purpose of

View File

@ -6,11 +6,17 @@
*/
package org.hibernate.cache.spi;
import org.hibernate.metamodel.model.domain.NavigableRole;
import org.jboss.logging.BasicLogger;
import org.jboss.logging.Logger;
import org.jboss.logging.annotations.LogMessage;
import org.jboss.logging.annotations.Message;
import org.jboss.logging.annotations.MessageLogger;
import org.jboss.logging.annotations.ValidIdRange;
import static org.jboss.logging.Logger.Level.WARN;
/**
* @author Steve Ebersole
*/
@ -22,11 +28,18 @@ public interface SecondLevelCacheLogger extends BasicLogger {
"org.hibernate.orm.cache"
);
enum RegionAccessType {
ENTITY,
NATURAL_ID,
COLLECTION,
QUERY_RESULTS,
TIMESTAMPS
}
@LogMessage( level = WARN )
@Message(
value = "Read-only caching was requested for mutable entity [%s]",
id = 90001001
)
void readOnlyCachingMutableEntity(NavigableRole navigableRole);
@LogMessage( level = WARN )
@Message(
value = "Read-only caching was requested for mutable natural-id for entity [%s]",
id = 90001002
)
void readOnlyCachingMutableNaturalId(NavigableRole navigableRole);
}

View File

@ -0,0 +1,16 @@
/*
* 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;
/**
* @author Steve Ebersole
*/
public class StandardCacheTransactionSynchronization extends AbstractCacheTransactionSynchronization {
public StandardCacheTransactionSynchronization(RegionFactory regionFactory) {
super( regionFactory );
}
}

View File

@ -12,6 +12,6 @@
public interface TimestampsRegion extends DirectAccessRegion {
@Override
default void clear() {
getAccess().clearCache();
getStorageAccess().clearCache();
}
}

View File

@ -95,7 +95,7 @@ public void accept(Serializable serializable) {
@Override
default void clear() throws CacheException {
getRegion().getAccess().clearCache();
getRegion().getStorageAccess().clearCache();
}
@Override

View File

@ -4,13 +4,9 @@
* 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;
package org.hibernate.cache.spi.support;
import java.util.Collections;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import org.hibernate.cache.spi.AbstractDomainDataRegion;
import org.hibernate.cache.spi.DomainDataRegion;
import org.hibernate.cache.spi.access.CachedDomainDataAccess;
import org.hibernate.cache.spi.access.SoftLock;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
@ -23,63 +19,47 @@
public abstract class AbstractCachedDomainDataAccess implements CachedDomainDataAccess, AbstractDomainDataRegion.Destructible {
private static final Logger log = Logger.getLogger( AbstractCachedDomainDataAccess.class );
private final DomainDataRegionImpl region;
private final DomainDataRegion region;
private final DomainDataStorageAccess storageAccess;
private Map data;
protected AbstractCachedDomainDataAccess(DomainDataRegionImpl region) {
protected AbstractCachedDomainDataAccess(
DomainDataRegion region,
DomainDataStorageAccess storageAccess) {
this.region = region;
this.storageAccess = storageAccess;
}
@Override
public DomainDataRegionImpl getRegion() {
public DomainDataRegion getRegion() {
return region;
}
protected Object getFromCache(Object key) {
log.debugf( "Locating entry in cache data map [region=`%s`] : %s", key );
if ( data == null ) {
return null;
}
return data.get( 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 data map [region=`%s`] : %s -> %s", getRegion().getName(), key, value );
getOrMakeData().put( key, 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 data map [region=`%s`] : %s", key );
if ( data != null ) {
data.remove( key );
}
log.debugf( "Removing entry from cache storage [region=`%s`] : %s", key );
storageAccess.removeFromCache( key );
}
@SuppressWarnings({"unchecked", "WeakerAccess"})
protected void clearCache() {
log.debugf( "Clearing cache data map [region=`%s`]" );
if ( data != null ) {
data.clear();
}
}
public Map getData() {
return data == null ? Collections.emptyMap() : Collections.unmodifiableMap( data );
}
private Map getOrMakeData() {
if ( data == null ) {
data = new ConcurrentHashMap();
}
return data;
storageAccess.clearCache();
}
@Override
public boolean contains(Object key) {
return data != null && data.containsKey( key );
return storageAccess.contains( key );
}
@Override
@ -142,8 +122,6 @@ public void evictAll() {
@Override
public void destroy() {
if ( data != null ) {
data.clear();
}
storageAccess.release();
}
}

View File

@ -4,8 +4,11 @@
* 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;
package org.hibernate.cache.spi.support;
import org.hibernate.cache.cfg.spi.CollectionDataCachingConfig;
import org.hibernate.cache.spi.CacheKeysFactory;
import org.hibernate.cache.spi.DomainDataRegion;
import org.hibernate.cache.spi.access.CollectionDataAccess;
import org.hibernate.cache.spi.access.SoftLock;
import org.hibernate.engine.spi.SessionFactoryImplementor;
@ -15,22 +18,29 @@
/**
* @author Steve Ebersole
*/
public abstract class BaseCollectionDataAccess
public abstract class AbstractCollectionDataAccess
extends AbstractCachedDomainDataAccess
implements CollectionDataAccess {
public BaseCollectionDataAccess(DomainDataRegionImpl region) {
super( region );
private final CacheKeysFactory keysFactory;
public AbstractCollectionDataAccess(
DomainDataRegion region,
CacheKeysFactory keysFactory,
DomainDataStorageAccess storageAccess,
CollectionDataCachingConfig config) {
super( region, storageAccess );
this.keysFactory = keysFactory;
}
@Override
public Object generateCacheKey(Object id, CollectionPersister persister, SessionFactoryImplementor factory, String tenantIdentifier) {
return getRegion().getEffectiveKeysFactory().createCollectionKey( id, persister, factory, tenantIdentifier );
return keysFactory.createCollectionKey( id, persister, factory, tenantIdentifier );
}
@Override
public Object getCacheKeyId(Object cacheKey) {
return getRegion().getEffectiveKeysFactory().getCollectionId( cacheKey );
return keysFactory.getCollectionId( cacheKey );
}
@Override

View File

@ -4,7 +4,7 @@
* 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;
package org.hibernate.cache.spi.support;
import java.util.Collections;
import java.util.Map;
@ -16,6 +16,8 @@
import org.hibernate.cache.cfg.spi.DomainDataRegionConfig;
import org.hibernate.cache.cfg.spi.EntityDataCachingConfig;
import org.hibernate.cache.cfg.spi.NaturalIdDataCachingConfig;
import org.hibernate.cache.spi.DomainDataRegion;
import org.hibernate.cache.spi.RegionFactory;
import org.hibernate.cache.spi.access.CollectionDataAccess;
import org.hibernate.cache.spi.access.EntityDataAccess;
import org.hibernate.cache.spi.access.NaturalIdDataAccess;
@ -25,10 +27,8 @@
/**
* @author Steve Ebersole
*/
public abstract class AbstractDomainDataRegion implements DomainDataRegion {
private final String name;
public abstract class AbstractDomainDataRegion extends AbstractRegion implements DomainDataRegion {
private final SessionFactoryImplementor sessionFactory;
private final RegionFactory regionFactory;
private final Map<NavigableRole,EntityDataAccess> entityDataAccessMap;
private final Map<NavigableRole,NaturalIdDataAccess> naturalIdDataAccessMap;
@ -37,35 +37,30 @@ public abstract class AbstractDomainDataRegion implements DomainDataRegion {
public AbstractDomainDataRegion(
DomainDataRegionConfig regionConfig,
RegionFactory regionFactory,
DomainDataStorageAccess storageAccess,
DomainDataRegionBuildingContext buildingContext) {
this.name = regionConfig.getRegionName();
super( regionFactory.qualify( regionConfig.getRegionName() ), regionFactory, storageAccess );
this.sessionFactory = buildingContext.getSessionFactory();
this.regionFactory = regionFactory;
this.entityDataAccessMap = generateEntityDataAccessMap( regionConfig );
this.naturalIdDataAccessMap = generateNaturalIdDataAccessMap( regionConfig );
this.collectionDataAccessMap = generateCollectionDataAccessMap( regionConfig );
}
@Override
public String getName() {
return name;
}
public SessionFactoryImplementor getSessionFactory() {
return sessionFactory;
}
@Override
public RegionFactory getRegionFactory() {
return regionFactory;
public DomainDataStorageAccess getStorageAccess() {
return (DomainDataStorageAccess) super.getStorageAccess();
}
@Override
public EntityDataAccess getEntityDataAccess(NavigableRole rootEntityRole) {
final EntityDataAccess access = entityDataAccessMap.get( rootEntityRole );
if ( access == null ) {
// todo (6.0) : is it an error here if the entity is not configured for caching (no map hit)?
throw new IllegalArgumentException( "Caching was not configured for entity : " + rootEntityRole.getFullPath() );
}
return access;
}
@ -75,7 +70,7 @@ public EntityDataAccess getEntityDataAccess(NavigableRole rootEntityRole) {
public NaturalIdDataAccess getNaturalIdDataAccess(NavigableRole rootEntityRole) {
final NaturalIdDataAccess access = naturalIdDataAccessMap.get( rootEntityRole );
if ( access == null ) {
// todo (6.0) : is it an error here if the entity is not configured for caching (no map hit)?
throw new IllegalArgumentException( "Caching was not configured for entity natural-id : " + rootEntityRole.getFullPath() );
}
return access;
}
@ -84,7 +79,7 @@ public NaturalIdDataAccess getNaturalIdDataAccess(NavigableRole rootEntityRole)
public CollectionDataAccess getCollectionDataAccess(NavigableRole collectionRole) {
final CollectionDataAccess access = collectionDataAccessMap.get( collectionRole );
if ( access == null ) {
// todo (6.0) : is it an error here if the entity is not configured for caching (no map hit)?
throw new IllegalArgumentException( "Caching was not configured for collection : " + collectionRole.getFullPath() );
}
return access;
}
@ -159,6 +154,8 @@ public void clear() {
for ( CollectionDataAccess cacheAccess : collectionDataAccessMap.values() ) {
cacheAccess.evictAll();
}
getStorageAccess().release();
}

View File

@ -4,8 +4,10 @@
* 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;
package org.hibernate.cache.spi.support;
import org.hibernate.cache.spi.CacheKeysFactory;
import org.hibernate.cache.spi.DomainDataRegion;
import org.hibernate.cache.spi.access.EntityDataAccess;
import org.hibernate.cache.spi.access.SoftLock;
import org.hibernate.engine.spi.SessionFactoryImplementor;
@ -15,12 +17,18 @@
/**
* @author Steve Ebersole
*/
public abstract class BaseEntityDataAccess
public abstract class AbstractEntityDataAccess
extends AbstractCachedDomainDataAccess
implements EntityDataAccess {
public BaseEntityDataAccess(DomainDataRegionImpl region) {
super( region );
private final CacheKeysFactory cacheKeysFactory;
public AbstractEntityDataAccess(
DomainDataRegion region,
CacheKeysFactory cacheKeysFactory,
DomainDataStorageAccess storageAccess) {
super( region, storageAccess );
this.cacheKeysFactory = cacheKeysFactory;
}
@Override
@ -29,7 +37,7 @@ public Object generateCacheKey(
EntityPersister rootEntityDescriptor,
SessionFactoryImplementor factory,
String tenantIdentifier) {
return getRegion().getEffectiveKeysFactory().createEntityKey(
return cacheKeysFactory.createEntityKey(
id,
rootEntityDescriptor,
factory,
@ -39,7 +47,7 @@ public Object generateCacheKey(
@Override
public Object getCacheKeyId(Object cacheKey) {
return getRegion().getEffectiveKeysFactory().getEntityId( cacheKey );
return cacheKeysFactory.getEntityId( cacheKey );
}
@Override

View File

@ -4,8 +4,11 @@
* 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;
package org.hibernate.cache.spi.support;
import org.hibernate.cache.cfg.spi.NaturalIdDataCachingConfig;
import org.hibernate.cache.spi.CacheKeysFactory;
import org.hibernate.cache.spi.DomainDataRegion;
import org.hibernate.cache.spi.access.NaturalIdDataAccess;
import org.hibernate.cache.spi.access.SoftLock;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
@ -14,9 +17,16 @@
/**
* @author Steve Ebersole
*/
public abstract class BaseNaturalIdDataAccess extends AbstractCachedDomainDataAccess implements NaturalIdDataAccess {
public BaseNaturalIdDataAccess(DomainDataRegionImpl region) {
super( region );
public abstract class AbstractNaturalIdDataAccess extends AbstractCachedDomainDataAccess implements NaturalIdDataAccess {
private final CacheKeysFactory keysFactory;
public AbstractNaturalIdDataAccess(
DomainDataRegion region,
CacheKeysFactory keysFactory,
DomainDataStorageAccess storageAccess,
NaturalIdDataCachingConfig config) {
super( region, storageAccess );
this.keysFactory = keysFactory;
}
@Override
@ -24,12 +34,12 @@ public Object generateCacheKey(
Object[] naturalIdValues,
EntityPersister persister,
SharedSessionContractImplementor session) {
return getRegion().getEffectiveKeysFactory().createNaturalIdKey( naturalIdValues, persister, session );
return keysFactory.createNaturalIdKey( naturalIdValues, persister, session );
}
@Override
public Object[] getNaturalIdValues(Object cacheKey) {
return getRegion().getEffectiveKeysFactory().getNaturalIdValues( cacheKey );
return keysFactory.getNaturalIdValues( cacheKey );
}

View File

@ -4,16 +4,17 @@
* 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;
package org.hibernate.cache.spi.support;
import java.io.Serializable;
import java.util.Comparator;
import java.util.Locale;
import java.util.UUID;
import java.util.concurrent.atomic.AtomicLong;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
import org.hibernate.cache.spi.SecondLevelCacheLogger.RegionAccessType;
import org.hibernate.cache.spi.DomainDataRegion;
import org.hibernate.cache.spi.access.SoftLock;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
@ -32,8 +33,10 @@ public abstract class AbstractReadWriteAccess extends AbstractCachedDomainDataAc
private final Lock readLock = reentrantReadWriteLock.readLock();
private final Lock writeLock = reentrantReadWriteLock.writeLock();
protected AbstractReadWriteAccess(DomainDataRegionImpl region) {
super( region );
protected AbstractReadWriteAccess(
DomainDataRegion domainDataRegion,
DomainDataStorageAccess storageAccess) {
super( domainDataRegion, storageAccess );
}
protected abstract Comparator getVersionComparator();
@ -292,6 +295,15 @@ public boolean isUnlockable(SoftLock lock) {
public SoftLockImpl lock(long timeout, UUID uuid, long lockId) {
return new SoftLockImpl( timeout, uuid, lockId, version );
}
@Override
public String toString() {
return String.format(
Locale.ROOT,
"read-write Item(%s)",
getValue()
);
}
}
/**

View File

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

View File

@ -4,20 +4,27 @@
* 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;
package org.hibernate.cache.spi.support;
import org.hibernate.cache.cfg.spi.CollectionDataCachingConfig;
import org.hibernate.cache.spi.CacheKeysFactory;
import org.hibernate.cache.spi.DomainDataRegion;
import org.hibernate.cache.spi.access.SoftLock;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
/**
* Standard support for {@link org.hibernate.cache.spi.access.CollectionDataAccess}
* using the {@link org.hibernate.cache.spi.access.AccessType#NONSTRICT_READ_WRITE} access type.
*
* @author Steve Ebersole
*/
public class CollectionNonStrictReadWriteAccess extends BaseCollectionDataAccess {
public class CollectionNonStrictReadWriteAccess extends AbstractCollectionDataAccess {
public CollectionNonStrictReadWriteAccess(
DomainDataRegionImpl region,
DomainDataRegion region,
CacheKeysFactory keysFactory,
DomainDataStorageAccess storageAccess,
CollectionDataCachingConfig config) {
super( region );
super( region, keysFactory, storageAccess, config );
}
@Override

View File

@ -0,0 +1,27 @@
/*
* 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.CollectionDataCachingConfig;
import org.hibernate.cache.spi.CacheKeysFactory;
import org.hibernate.cache.spi.DomainDataRegion;
/**
* Standard support for {@link org.hibernate.cache.spi.access.CollectionDataAccess}
* using the {@link org.hibernate.cache.spi.access.AccessType#READ_ONLY} access type.
*
* @author Steve Ebersole
*/
public class CollectionReadOnlyAccess extends AbstractCollectionDataAccess {
public CollectionReadOnlyAccess(
DomainDataRegion region,
CacheKeysFactory keysFactory,
DomainDataStorageAccess storageAccess,
CollectionDataCachingConfig config) {
super( region, keysFactory, storageAccess, config );
}
}

View File

@ -4,37 +4,45 @@
* 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;
package org.hibernate.cache.spi.support;
import java.util.Comparator;
import org.hibernate.cache.cfg.spi.CollectionDataCachingConfig;
import org.hibernate.cache.spi.SecondLevelCacheLogger;
import org.hibernate.cache.spi.CacheKeysFactory;
import org.hibernate.cache.spi.DomainDataRegion;
import org.hibernate.cache.spi.access.CollectionDataAccess;
import org.hibernate.cache.spi.access.SoftLock;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.metamodel.model.domain.NavigableRole;
import org.hibernate.persister.collection.CollectionPersister;
/**
* Standard support for {@link org.hibernate.cache.spi.access.CollectionDataAccess}
* using the {@link org.hibernate.cache.spi.access.AccessType#READ_WRITE} access type.
*
* @author Chris Cranford
* @author Steve Ebersole
*/
public class CollectionReadWriteAccess extends AbstractReadWriteAccess implements CollectionDataAccess {
private final NavigableRole collectionRole;
private final Comparator versionComparator;
private final CacheKeysFactory keysFactory;
public CollectionReadWriteAccess(
DomainDataRegionImpl region,
DomainDataRegion region,
CacheKeysFactory keysFactory,
DomainDataStorageAccess storageAccess,
CollectionDataCachingConfig config) {
super( region );
super( region, storageAccess );
this.keysFactory = keysFactory;
this.collectionRole = config.getNavigableRole();
this.versionComparator = config.getOwnerVersionComparator();
}
@Override
protected SecondLevelCacheLogger.RegionAccessType getAccessType() {
return SecondLevelCacheLogger.RegionAccessType.COLLECTION;
protected RegionAccessType getAccessType() {
return RegionAccessType.COLLECTION;
}
@Override
@ -43,12 +51,12 @@ public Object generateCacheKey(
CollectionPersister collectionDescriptor,
SessionFactoryImplementor factory,
String tenantIdentifier) {
return getRegion().getEffectiveKeysFactory().createCollectionKey( id, collectionDescriptor, factory, tenantIdentifier );
return keysFactory.createCollectionKey( id, collectionDescriptor, factory, tenantIdentifier );
}
@Override
public Object getCacheKeyId(Object cacheKey) {
return getRegion().getEffectiveKeysFactory().getCollectionId( cacheKey );
return keysFactory.getCollectionId( cacheKey );
}
@Override

View File

@ -0,0 +1,14 @@
/*
* 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;
/**
* @author Steve Ebersole
*/
public interface DomainDataStorageAccess extends StorageAccess {
void putFromLoad(Object key, Object value);
}

View File

@ -4,19 +4,28 @@
* 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;
package org.hibernate.cache.spi.support;
import org.hibernate.cache.CacheException;
import org.hibernate.cache.cfg.spi.EntityDataCachingConfig;
import org.hibernate.cache.spi.CacheKeysFactory;
import org.hibernate.cache.spi.DomainDataRegion;
import org.hibernate.cache.spi.access.SoftLock;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
/**
* Standard support for {@link org.hibernate.cache.spi.access.EntityDataAccess}
* using the {@link org.hibernate.cache.spi.access.AccessType#NONSTRICT_READ_WRITE} access type.
*
* @author Steve Ebersole
*/
public class EntityNonStrictReadWriteAccess extends BaseEntityDataAccess {
public EntityNonStrictReadWriteAccess(DomainDataRegionImpl domainDataRegion, EntityDataCachingConfig entityAccessConfig) {
super( domainDataRegion );
public class EntityNonStrictReadWriteAccess extends AbstractEntityDataAccess {
public EntityNonStrictReadWriteAccess(
DomainDataRegion domainDataRegion,
CacheKeysFactory keysFactory,
DomainDataStorageAccess storageAccess,
EntityDataCachingConfig entityAccessConfig) {
super( domainDataRegion, keysFactory, storageAccess );
}

View File

@ -4,22 +4,35 @@
* 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;
package org.hibernate.cache.spi.support;
import org.hibernate.cache.cfg.spi.EntityDataCachingConfig;
import org.hibernate.cache.spi.CacheKeysFactory;
import org.hibernate.cache.spi.DomainDataRegion;
import org.hibernate.cache.spi.SecondLevelCacheLogger;
import org.hibernate.cache.spi.access.SoftLock;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.jboss.logging.Logger;
/**
* Standard support for {@link org.hibernate.cache.spi.access.EntityDataAccess}
* using the {@link org.hibernate.cache.spi.access.AccessType#READ_ONLY} access type.
*
* @author Steve Ebersole
*/
public class EntityReadOnlyAccess extends BaseEntityDataAccess {
public class EntityReadOnlyAccess extends AbstractEntityDataAccess {
private static final Logger log = Logger.getLogger( EntityReadOnlyAccess.class );
public EntityReadOnlyAccess(DomainDataRegionImpl region, EntityDataCachingConfig congfig) {
super( region );
public EntityReadOnlyAccess(
DomainDataRegion region,
CacheKeysFactory cacheKeysFactory,
DomainDataStorageAccess storageAccess,
EntityDataCachingConfig config) {
super( region, cacheKeysFactory, storageAccess );
if ( config.isMutable() ) {
SecondLevelCacheLogger.INSTANCE.readOnlyCachingMutableEntity( config.getNavigableRole() );
}
}
@Override

View File

@ -4,12 +4,13 @@
* 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;
package org.hibernate.cache.spi.support;
import java.util.Comparator;
import org.hibernate.cache.cfg.spi.EntityDataCachingConfig;
import org.hibernate.cache.spi.SecondLevelCacheLogger;
import org.hibernate.cache.spi.CacheKeysFactory;
import org.hibernate.cache.spi.DomainDataRegion;
import org.hibernate.cache.spi.access.EntityDataAccess;
import org.hibernate.cache.spi.access.SoftLock;
import org.hibernate.engine.spi.SessionFactoryImplementor;
@ -17,21 +18,30 @@
import org.hibernate.persister.entity.EntityPersister;
/**
* Standard support for {@link org.hibernate.cache.spi.access.EntityDataAccess}
* using the {@link org.hibernate.cache.spi.access.AccessType#READ_WRITE} access type.
*
* @author Steve Ebersole
*/
public class EntityReadWriteAccess extends AbstractReadWriteAccess implements EntityDataAccess {
private final CacheKeysFactory keysFactory;
private final Comparator versionComparator;
protected EntityReadWriteAccess(DomainDataRegionImpl region, EntityDataCachingConfig entityAccessConfig) {
super( region );
public EntityReadWriteAccess(
DomainDataRegion domainDataRegion,
CacheKeysFactory keysFactory,
DomainDataStorageAccess storageAccess,
EntityDataCachingConfig entityAccessConfig) {
super( domainDataRegion, storageAccess );
this.keysFactory = keysFactory;
this.versionComparator = entityAccessConfig.getVersionComparatorAccess() == null
? null
: entityAccessConfig.getVersionComparatorAccess().get();
}
@Override
protected SecondLevelCacheLogger.RegionAccessType getAccessType() {
return SecondLevelCacheLogger.RegionAccessType.ENTITY;
protected RegionAccessType getAccessType() {
return RegionAccessType.ENTITY;
}
@Override
@ -45,12 +55,12 @@ public Object generateCacheKey(
EntityPersister rootEntityDescriptor,
SessionFactoryImplementor factory,
String tenantIdentifier) {
return getRegion().getEffectiveKeysFactory().createEntityKey( id, rootEntityDescriptor, factory, tenantIdentifier );
return keysFactory.createEntityKey( id, rootEntityDescriptor, factory, tenantIdentifier );
}
@Override
public Object getCacheKeyId(Object cacheKey) {
return getRegion().getEffectiveKeysFactory().getEntityId( cacheKey );
return keysFactory.getEntityId( cacheKey );
}
@Override

View File

@ -4,20 +4,27 @@
* 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;
package org.hibernate.cache.spi.support;
import org.hibernate.cache.cfg.spi.NaturalIdDataCachingConfig;
import org.hibernate.cache.spi.CacheKeysFactory;
import org.hibernate.cache.spi.DomainDataRegion;
import org.hibernate.cache.spi.access.SoftLock;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
/**
* Standard support for {@link org.hibernate.cache.spi.access.NaturalIdDataAccess}
* using the {@link org.hibernate.cache.spi.access.AccessType#NONSTRICT_READ_WRITE} access type.
*
* @author Steve Ebersole
*/
public class NaturalIdNonStrictReadWriteAccess extends BaseNaturalIdDataAccess {
public class NaturalIdNonStrictReadWriteAccess extends AbstractNaturalIdDataAccess {
public NaturalIdNonStrictReadWriteAccess(
DomainDataRegionImpl region,
NaturalIdDataCachingConfig naturalIdDataCachingConfig) {
super( region );
DomainDataRegion region,
CacheKeysFactory keysFactory,
DomainDataStorageAccess storageAccess,
NaturalIdDataCachingConfig config) {
super( region, keysFactory, storageAccess, config );
}
@Override

View File

@ -0,0 +1,41 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
*/
package org.hibernate.cache.spi.support;
import org.hibernate.cache.cfg.spi.NaturalIdDataCachingConfig;
import org.hibernate.cache.spi.CacheKeysFactory;
import org.hibernate.cache.spi.DomainDataRegion;
import org.hibernate.cache.spi.SecondLevelCacheLogger;
import org.hibernate.cache.spi.access.SoftLock;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
/**
* Standard support for {@link org.hibernate.cache.spi.access.NaturalIdDataAccess}
* using the {@link org.hibernate.cache.spi.access.AccessType#READ_ONLY} access type.
*
* @author Steve Ebersole
*/
public class NaturalIdReadOnlyAccess extends AbstractNaturalIdDataAccess {
public NaturalIdReadOnlyAccess(
DomainDataRegion region,
CacheKeysFactory keysFactory,
DomainDataStorageAccess storageAccess,
NaturalIdDataCachingConfig config) {
super( region, keysFactory, storageAccess, config );
if ( config.isMutable() ) {
SecondLevelCacheLogger.INSTANCE.readOnlyCachingMutableNaturalId( config.getNavigableRole() );
}
}
@Override
public void unlockItem(
SharedSessionContractImplementor session,
Object key,
SoftLock lock) {
evict( key );
}
}

View File

@ -4,31 +4,39 @@
* 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;
package org.hibernate.cache.spi.support;
import java.util.Comparator;
import org.hibernate.cache.cfg.spi.NaturalIdDataCachingConfig;
import org.hibernate.cache.spi.SecondLevelCacheLogger;
import org.hibernate.cache.spi.CacheKeysFactory;
import org.hibernate.cache.spi.DomainDataRegion;
import org.hibernate.cache.spi.access.NaturalIdDataAccess;
import org.hibernate.cache.spi.access.SoftLock;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.persister.entity.EntityPersister;
/**
* Standard support for {@link org.hibernate.cache.spi.access.NaturalIdDataAccess}
* using the {@link org.hibernate.cache.spi.access.AccessType#READ_WRITE} access type.
*
* @author Steve Ebersole
*/
public class NaturalIdReadWriteAccess extends AbstractReadWriteAccess implements NaturalIdDataAccess {
private final CacheKeysFactory keysFactory;
public NaturalIdReadWriteAccess(
DomainDataRegionImpl region,
DomainDataRegion region,
CacheKeysFactory keysFactory,
DomainDataStorageAccess storageAccess,
NaturalIdDataCachingConfig naturalIdDataCachingConfig) {
super( region );
super( region, storageAccess );
this.keysFactory = keysFactory;
}
@Override
protected SecondLevelCacheLogger.RegionAccessType getAccessType() {
return SecondLevelCacheLogger.RegionAccessType.NATURAL_ID;
protected RegionAccessType getAccessType() {
return RegionAccessType.NATURAL_ID;
}
@Override
@ -42,12 +50,12 @@ public Object generateCacheKey(
Object[] naturalIdValues,
EntityPersister rootEntityDescriptor,
SharedSessionContractImplementor session) {
return getRegion().getEffectiveKeysFactory().createNaturalIdKey( naturalIdValues, rootEntityDescriptor, session );
return keysFactory.createNaturalIdKey( naturalIdValues, rootEntityDescriptor, session );
}
@Override
public Object[] getNaturalIdValues(Object cacheKey) {
return getRegion().getEffectiveKeysFactory().getNaturalIdValues( cacheKey );
return keysFactory.getNaturalIdValues( cacheKey );
}
@Override

View File

@ -0,0 +1,18 @@
/*
* 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;
/**
* @author Steve Ebersole
*/
public enum RegionAccessType {
ENTITY,
NATURAL_ID,
COLLECTION,
QUERY_RESULTS,
TIMESTAMPS
}

View File

@ -0,0 +1,36 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
*/
package org.hibernate.cache.spi.support;
import org.hibernate.boot.spi.SessionFactoryOptions;
/**
* @author Steve Ebersole
*/
public class RegionNameQualifier {
/**
* Singleton access
*/
public static final RegionNameQualifier INSTANCE = new RegionNameQualifier();
public String qualify(String regionName, SessionFactoryOptions options) {
final String prefix = options.getCacheRegionPrefix();
if ( prefix == null ) {
return regionName;
}
else {
if ( regionName.startsWith( prefix ) ) {
return regionName.substring( prefix.length() );
}
return prefix + regionName;
}
}
private RegionNameQualifier() {
}
}

View File

@ -1,11 +1,12 @@
/*
* 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>.
* 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.time;
package org.hibernate.cache.spi.support;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicLong;
/**
@ -17,11 +18,12 @@
* @author Hibernate team
* @author Alex Snaps
*/
public final class Timestamper {
public final class SimpleTimestamper {
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 final short ONE_MS = 1 << BIN_DIGITS;
public static long next() {
while ( true ) {
long base = System.currentTimeMillis() << BIN_DIGITS;
@ -36,6 +38,10 @@ public static long next() {
}
}
private Timestamper() {
public static int timeOut() {
return (int) TimeUnit.SECONDS.toMillis( 60 ) * ONE_MS;
}
private SimpleTimestamper() {
}
}

View File

@ -0,0 +1,27 @@
/*
* 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;
/**
* @author Steve Ebersole
*/
public interface StorageAccess {
default boolean contains(Object key) {
return getFromCache( key ) != null;
}
Object getFromCache(Object key);
void putIntoCache(Object key, Object value);
void removeFromCache(Object key);
void clearCache();
void release();
}

View File

@ -19,7 +19,6 @@
import org.hibernate.annotations.Cache;
import org.hibernate.annotations.CacheConcurrencyStrategy;
import org.hibernate.annotations.Formula;
import org.hibernate.cache.spi.DomainDataRegion;
import org.hibernate.cache.spi.access.EntityDataAccess;
import org.hibernate.cache.spi.entry.StandardCacheEntryImpl;
import org.hibernate.cfg.AvailableSettings;
@ -28,7 +27,6 @@
import org.hibernate.persister.entity.EntityPersister;
import org.hibernate.testing.bytecode.enhancement.BytecodeEnhancerRunner;
import org.hibernate.testing.cache.EntityReadWriteAccess;
import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase;
import org.junit.Before;
import org.junit.Test;

View File

@ -16,7 +16,6 @@
import org.hibernate.testing.TestForIssue;
import org.hibernate.testing.cache.CachingRegionFactory;
import org.hibernate.testing.cache.EntityReadWriteAccess;
import org.hibernate.testing.junit4.BaseNonConfigCoreFunctionalTestCase;
import org.junit.Test;

View File

@ -17,7 +17,6 @@
import org.hibernate.testing.TestForIssue;
import org.hibernate.testing.cache.CachingRegionFactory;
import org.hibernate.testing.cache.EntityReadWriteAccess;
import org.hibernate.testing.junit4.BaseNonConfigCoreFunctionalTestCase;
import org.junit.Test;

View File

@ -4,15 +4,11 @@
* 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;
package org.hibernate.cache.jcache;
/**
* @author Steve Ebersole
*/
public class SoftLockingSupport {
private SoftLockingSupport() {
}
public interface ConfigSettings {
String SIMPLE_FACTORY_NAME = "jcache";
}

View File

@ -1,42 +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;
import javax.cache.Cache;
import org.hibernate.boot.spi.SessionFactoryOptions;
import org.hibernate.cache.CacheException;
import org.hibernate.cache.jcache.access.NonStrictCollectionRegionAccessStrategy;
import org.hibernate.cache.jcache.access.ReadOnlyCollectionRegionAccessStrategy;
import org.hibernate.cache.jcache.access.ReadWriteCollectionRegionAccessStrategy;
import org.hibernate.cache.spi.access.AccessType;
/**
* @author Alex Snaps
*/
public class JCacheCollectionRegion extends JCacheTransactionalDataRegion implements CollectionRegion {
public JCacheCollectionRegion(Cache<Object, Object> cache, CacheDataDescription metadata, SessionFactoryOptions options) {
super( cache, metadata, options );
}
@Override
public CollectionRegionAccessStrategy buildAccessStrategy(AccessType accessType) throws CacheException {
switch ( accessType ) {
case READ_ONLY:
return new ReadOnlyCollectionRegionAccessStrategy( this );
case NONSTRICT_READ_WRITE:
return new NonStrictCollectionRegionAccessStrategy( this );
case READ_WRITE:
return new ReadWriteCollectionRegionAccessStrategy( this );
case TRANSACTIONAL:
throw new UnsupportedOperationException( "Implement me!" );
default:
throw new UnsupportedOperationException( "Unknown AccessType: " + accessType.name() );
}
}
}

View File

@ -1,47 +0,0 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
*/
package org.hibernate.cache.jcache;
import javax.cache.Cache;
import org.hibernate.boot.spi.SessionFactoryOptions;
import org.hibernate.cache.CacheException;
import org.hibernate.cache.jcache.access.NonStrictEntityRegionAccessStrategy;
import org.hibernate.cache.jcache.access.ReadOnlyEntityRegionAccessStrategy;
import org.hibernate.cache.jcache.access.ReadWriteEntityRegionAccessStrategy;
import org.hibernate.cache.spi.access.AccessType;
/**
* @author Alex Snaps
*/
public class JCacheEntityRegion extends JCacheTransactionalDataRegion implements EntityRegion {
public JCacheEntityRegion(Cache<Object, Object> cache, CacheDataDescription metadata, SessionFactoryOptions options) {
super( cache, metadata, options );
}
@Override
public EntityRegionAccessStrategy buildAccessStrategy(AccessType accessType) throws CacheException {
throwIfAccessTypeUnsupported( accessType );
switch ( accessType ) {
case READ_ONLY:
return new ReadOnlyEntityRegionAccessStrategy( this );
case NONSTRICT_READ_WRITE:
return new NonStrictEntityRegionAccessStrategy( this );
case READ_WRITE:
return new ReadWriteEntityRegionAccessStrategy( this );
case TRANSACTIONAL:
return createTransactionalEntityRegionAccessStrategy();
default:
throw new IllegalArgumentException( "Unknown AccessType: " + accessType );
}
}
protected EntityRegionAccessStrategy createTransactionalEntityRegionAccessStrategy() {
throw new UnsupportedOperationException("No org.hibernate.cache.spi.access.AccessType.TRANSACTIONAL support");
}
}

View File

@ -1,43 +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;
import javax.cache.Cache;
import org.hibernate.cache.CacheException;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
/**
* @author Alex Snaps
*/
public class JCacheGeneralDataRegion extends JCacheRegion implements GeneralDataRegion {
public JCacheGeneralDataRegion(Cache<Object, Object> cache) {
super( cache );
}
@Override
public Object get(SharedSessionContractImplementor session, Object key) throws CacheException {
return cache.get( key );
}
@Override
public void put(SharedSessionContractImplementor session, Object key, Object value) throws CacheException {
cache.put( key, value );
}
@Override
public void evict(Object key) throws CacheException {
cache.remove( key );
}
@Override
public void evictAll() throws CacheException {
cache.removeAll();
}
}

View File

@ -1,42 +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;
import javax.cache.Cache;
import org.hibernate.boot.spi.SessionFactoryOptions;
import org.hibernate.cache.CacheException;
import org.hibernate.cache.jcache.access.NonStrictNaturalIdRegionAccessStrategy;
import org.hibernate.cache.jcache.access.ReadOnlyNaturalIdRegionAccessStrategy;
import org.hibernate.cache.jcache.access.ReadWriteNaturalIdRegionAccessStrategy;
import org.hibernate.cache.spi.access.AccessType;
/**
* @author Alex Snaps
*/
public class JCacheNaturalIdRegion extends JCacheTransactionalDataRegion implements NaturalIdRegion {
public JCacheNaturalIdRegion(Cache<Object, Object> cache, CacheDataDescription metadata, SessionFactoryOptions options) {
super( cache, metadata, options );
}
@Override
public NaturalIdRegionAccessStrategy buildAccessStrategy(AccessType accessType) throws CacheException {
switch ( accessType ) {
case READ_ONLY:
return new ReadOnlyNaturalIdRegionAccessStrategy( this );
case NONSTRICT_READ_WRITE:
return new NonStrictNaturalIdRegionAccessStrategy( this );
case READ_WRITE:
return new ReadWriteNaturalIdRegionAccessStrategy( this );
case TRANSACTIONAL:
throw new UnsupportedOperationException( "Implement me!" );
default:
throw new UnsupportedOperationException( "Unknown AccessType: " + accessType.name() );
}
}
}

View File

@ -1,22 +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;
import javax.cache.Cache;
import org.hibernate.cache.spi.QueryResultsRegion;
/**
* @author Alex Snaps
*/
public class JCacheQueryResultsRegion extends JCacheGeneralDataRegion implements QueryResultsRegion {
public JCacheQueryResultsRegion(Cache<Object, Object> cache) {
super( cache );
}
}

View File

@ -1,73 +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;
import java.util.HashMap;
import java.util.Map;
import javax.cache.Cache;
import org.hibernate.cache.CacheException;
import org.hibernate.cache.spi.Region;
/**
* @author Alex Snaps
*/
public class JCacheRegion implements Region {
protected final Cache<Object, Object> cache;
public JCacheRegion(Cache<Object, Object> cache) {
if(cache == null) {
throw new NullPointerException("JCacheRegion requires a Cache!");
}
this.cache = cache;
}
public String getName() {
return cache.getName();
}
public void destroy() throws CacheException {
cache.getCacheManager().destroyCache( cache.getName() );
}
public boolean contains(Object key) {
return cache.containsKey( key );
}
public long getSizeInMemory() {
return -1;
}
public long getElementCountInMemory() {
return -1;
}
public long getElementCountOnDisk() {
return -1;
}
public Map toMap() {
final Map<Object, Object> map = new HashMap<Object, Object>();
for ( Cache.Entry<Object, Object> entry : cache ) {
map.put( entry.getKey(), entry.getValue() );
}
return map;
}
public long nextTimestamp() {
return JCacheRegionFactory.nextTS();
}
public int getTimeout() {
return JCacheRegionFactory.timeOut();
}
Cache<Object, Object> getCache() {
return cache;
}
}

View File

@ -1,221 +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;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.Properties;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
import javax.cache.Cache;
import javax.cache.CacheManager;
import javax.cache.Caching;
import javax.cache.configuration.Configuration;
import javax.cache.configuration.MutableConfiguration;
import javax.cache.spi.CachingProvider;
import org.hibernate.boot.spi.SessionFactoryOptions;
import org.hibernate.cache.CacheException;
import org.hibernate.cache.jcache.time.Timestamper;
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.jboss.logging.Logger;
/**
* @author Alex Snaps
*/
public class JCacheRegionFactory implements RegionFactory {
private static final String PROP_PREFIX = "hibernate.javax.cache";
public static final String PROVIDER = PROP_PREFIX + ".provider";
public static final String CONFIG_URI = PROP_PREFIX + ".uri";
private static final JCacheMessageLogger LOG = Logger.getMessageLogger(
JCacheMessageLogger.class,
JCacheRegionFactory.class.getName()
);
static long nextTS() {
return Timestamper.next();
}
static int timeOut() {
return (int) TimeUnit.SECONDS.toMillis( 60 ) * Timestamper.ONE_MS;
}
private final AtomicBoolean started = new AtomicBoolean( false );
private volatile CacheManager cacheManager;
private SessionFactoryOptions options;
@Override
public void start(final SessionFactoryOptions options, final Properties properties) throws CacheException {
if ( started.compareAndSet( false, true ) ) {
synchronized ( this ) {
this.options = options;
try {
this.cacheManager = getCacheManager( properties );
}
finally {
if ( this.cacheManager == null ) {
started.set( false );
}
}
}
}
else {
LOG.attemptToRestartAlreadyStartedJCacheProvider();
}
}
@Override
public void stop() {
if ( started.compareAndSet( true, false ) ) {
synchronized ( this ) {
cacheManager.close();
cacheManager = null;
}
}
else {
LOG.attemptToRestopAlreadyStoppedJCacheProvider();
}
}
@Override
public boolean isMinimalPutsEnabledByDefault() {
return true;
}
@Override
public AccessType getDefaultAccessType() {
return AccessType.READ_WRITE;
}
@Override
public long nextTimestamp() {
return nextTS();
}
@Override
public EntityRegion buildEntityRegion(final String regionName, final Properties properties, final CacheDataDescription metadata)
throws CacheException {
final Cache<Object, Object> cache = getOrCreateCache( regionName, properties, metadata );
return new JCacheEntityRegion( cache, metadata, options );
}
@Override
public NaturalIdRegion buildNaturalIdRegion(final String regionName, final Properties properties, final CacheDataDescription metadata)
throws CacheException {
final Cache<Object, Object> cache = getOrCreateCache( regionName, properties, metadata );
return new JCacheNaturalIdRegion( cache, metadata, options );
}
@Override
public CollectionRegion buildCollectionRegion(final String regionName, final Properties properties, final CacheDataDescription metadata)
throws CacheException {
final Cache<Object, Object> cache = getOrCreateCache( regionName, properties, metadata );
return new JCacheCollectionRegion( cache, metadata, options );
}
@Override
public QueryResultsRegion buildQueryResultsRegion(final String regionName, final Properties properties)
throws CacheException {
final Cache<Object, Object> cache = getOrCreateCache( regionName, properties, null );
return new JCacheQueryResultsRegion( cache );
}
@Override
public TimestampsRegion buildTimestampsRegion(final String regionName, final Properties properties)
throws CacheException {
final Cache<Object, Object> cache = getOrCreateCache( regionName, properties, null );
return new JCacheTimestampsRegion( cache );
}
boolean isStarted() {
return started.get() && cacheManager != null;
}
protected SessionFactoryOptions getOptions() {
return options;
}
protected CachingProvider getCachingProvider(final Properties properties){
final CachingProvider cachingProvider;
final String provider = getProp( properties, PROVIDER );
if ( provider != null ) {
cachingProvider = Caching.getCachingProvider( provider );
}
else {
cachingProvider = Caching.getCachingProvider();
}
return cachingProvider;
}
protected CacheManager getCacheManager(final Properties properties){
final CachingProvider cachingProvider = getCachingProvider( properties );
final CacheManager cacheManager;
final String cacheManagerUri = getProp( properties, CONFIG_URI );
if ( cacheManagerUri != null ) {
URI uri;
try {
uri = new URI( cacheManagerUri );
}
catch ( URISyntaxException e ) {
throw new CacheException( "Couldn't create URI from " + cacheManagerUri, e );
}
cacheManager = cachingProvider.getCacheManager( uri, cachingProvider.getDefaultClassLoader() );
}
else {
cacheManager = cachingProvider.getCacheManager();
}
return cacheManager;
}
protected Cache<Object, Object> getOrCreateCache(String regionName, Properties properties, CacheDataDescription metadata) {
checkStatus();
final Cache<Object, Object> cache = cacheManager.getCache( regionName );
if ( cache == null ) {
try {
return createCache( regionName, properties, metadata );
}
catch ( CacheException e ) {
final Cache<Object, Object> existing = cacheManager.getCache( regionName );
if ( existing != null ) {
return existing;
}
throw e;
}
}
return cache;
}
protected Cache<Object, Object> createCache(String regionName, Properties properties, CacheDataDescription metadata) {
return cacheManager.createCache( regionName, newDefaultConfig( properties, metadata ) );
}
protected Configuration<Object, Object> newDefaultConfig(Properties properties, CacheDataDescription metadata) {
return new MutableConfiguration<Object, Object>();
}
protected CacheManager getCacheManager() {
return cacheManager;
}
protected String getProp(Properties properties, String prop) {
return properties != null ? properties.getProperty( prop ) : null;
}
protected void checkStatus() {
if(!isStarted()) {
throw new IllegalStateException("JCacheRegionFactory not yet started!");
}
}
}

View File

@ -1,22 +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;
import javax.cache.Cache;
import org.hibernate.cache.spi.TimestampsRegion;
/**
* @author Alex Snaps
*/
public class JCacheTimestampsRegion extends JCacheGeneralDataRegion implements TimestampsRegion {
public JCacheTimestampsRegion(Cache<Object, Object> cache) {
super( cache );
}
}

View File

@ -1,80 +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;
import java.util.EnumSet;
import java.util.Set;
import javax.cache.Cache;
import org.hibernate.boot.spi.SessionFactoryOptions;
import org.hibernate.cache.spi.access.AccessType;
/**
* @author Alex Snaps
*/
public class JCacheTransactionalDataRegion extends JCacheRegion implements TransactionalDataRegion {
private static final Set<AccessType> SUPPORTED_ACCESS_TYPES
= EnumSet.of( AccessType.READ_ONLY, AccessType.NONSTRICT_READ_WRITE, AccessType.READ_WRITE );
private final CacheDataDescription metadata;
private final SessionFactoryOptions options;
public JCacheTransactionalDataRegion(Cache<Object, Object> cache, CacheDataDescription metadata, SessionFactoryOptions options) {
super( cache );
this.metadata = metadata;
this.options = options;
}
@Override
public boolean isTransactionAware() {
return false;
}
@Override
public CacheDataDescription getCacheDataDescription() {
return metadata;
}
protected void throwIfAccessTypeUnsupported(AccessType accessType) {
if ( !supportedAccessTypes().contains( accessType ) ) {
throw new UnsupportedOperationException( "JCacheTransactionalDataRegion doesn't support " + accessType );
}
}
protected Set<AccessType> supportedAccessTypes() {
return SUPPORTED_ACCESS_TYPES;
}
public void clear() {
cache.removeAll();
}
public Object get(Object key) {
return cache.get( key );
}
public void remove(Object key) {
cache.remove( key );
}
public void put(Object key, Object value) {
cache.put( key, value );
}
public boolean putIfAbsent(Object key, Object value) {
return cache.putIfAbsent( key, value );
}
public boolean replace(Object key, Object expected, Object value) {
return cache.replace( key, expected, value );
}
public SessionFactoryOptions getSessionFactoryOptions() {
return options;
}
}

View File

@ -1,403 +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.access;
import java.io.Serializable;
import java.util.Comparator;
import java.util.UUID;
import java.util.concurrent.atomic.AtomicLong;
import org.hibernate.cache.CacheException;
import org.hibernate.cache.jcache.JCacheMessageLogger;
import org.hibernate.cache.jcache.JCacheTransactionalDataRegion;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.jboss.logging.Logger;
/**
* @author Alex Snaps
*/
abstract class AbstractReadWriteRegionAccessStrategy<R extends JCacheTransactionalDataRegion> {
private static final JCacheMessageLogger LOG = Logger.getMessageLogger(
JCacheMessageLogger.class,
AbstractReadWriteRegionAccessStrategy.class.getName()
);
protected final R region;
protected final Comparator versionComparator;
private final UUID uuid = UUID.randomUUID();
private final AtomicLong nextLockId = new AtomicLong();
private final AtomicLong nextItemId = new AtomicLong();
public AbstractReadWriteRegionAccessStrategy(R region) {
this.versionComparator = region.getCacheDataDescription().getVersionComparator();
this.region = region;
}
public R getRegion() {
return region;
}
public Object get(SharedSessionContractImplementor session, Object key, long txTimestamp) throws CacheException {
final Lockable item = (Lockable) region.get( key );
final boolean readable = item != null && item.isReadable( txTimestamp );
if ( readable ) {
return item.getValue();
}
else {
return null;
}
}
public boolean putFromLoad(SharedSessionContractImplementor session, Object key, Object value, long txTimestamp, Object version) throws CacheException {
while (true) {
Lockable item = (Lockable) region.get( key );
if (item == null) {
/*
* If the item is null due a softlock being evicted... then this
* is wrong, the in-doubt soft-lock could get replaced with the
* old value. All that can be done from a JCache perspective is
* to log a warning.
*/
if (region.putIfAbsent( key, new Item( value, version, txTimestamp, nextItemId() ))) {
return true;
}
}
else if (item.isWriteable( txTimestamp, version, versionComparator )) {
if (region.replace( key, item, new Item( value, version, txTimestamp, nextItemId() ))) {
return true;
}
}
else {
return false;
}
}
}
public boolean putFromLoad(SharedSessionContractImplementor session, Object key, Object value, long txTimestamp, Object version, boolean minimalPutOverride)
throws CacheException {
return putFromLoad( session, key, value, txTimestamp, version );
}
public SoftLock lockItem(SharedSessionContractImplementor session, Object key, Object version) throws CacheException {
long timeout = region.nextTimestamp() + region.getTimeout();
while (true) {
Lockable item = (Lockable) region.get( key );
if ( item == null ) {
/*
* What happens here if a previous soft-lock was evicted to make
* this null.
*/
Lock lock = new Lock(timeout, uuid, nextLockId(), version);
if (region.putIfAbsent( key, lock )) {
return lock;
}
}
else {
Lock lock = item.lock( timeout, uuid, nextLockId() );
if (region.replace(key, item, lock)) {
return lock;
}
}
}
}
public void unlockItem(SharedSessionContractImplementor session, Object key, SoftLock lock) throws CacheException {
while (true) {
Lockable item = (Lockable) region.get( key );
if (item != null && item.isUnlockable( lock )) {
if (region.replace(key, item, ((Lock) item ).unlock(region.nextTimestamp()))) {
return;
}
}
else {
handleMissingLock( key, item );
return;
}
}
}
public void remove(SharedSessionContractImplementor session, Object key) throws CacheException {
//this access strategy is asynchronous
}
public void removeAll() throws CacheException {
region.clear();
}
public void evict(Object key) throws CacheException {
region.remove( key );
}
public void evictAll() throws CacheException {
region.clear();
}
public SoftLock lockRegion() throws CacheException {
return null;
}
public void unlockRegion(SoftLock lock) throws CacheException {
region.clear();
}
private long nextLockId() {
return nextLockId.getAndIncrement();
}
protected long nextItemId() {
return nextItemId.getAndIncrement();
}
protected void handleMissingLock(Object key, Lockable lock) {
LOG.missingLock( region, key, lock );
long ts = region.nextTimestamp() + region.getTimeout();
// create new lock that times out immediately
Lock newLock = new Lock( ts, uuid, nextLockId.getAndIncrement(), null ).unlock( ts );
region.put( key, newLock );
}
/**
* Interface type implemented by all wrapper objects in the cache.
*/
protected static interface Lockable {
/**
* Returns <code>true</code> if the enclosed value can be read by a transaction started at the given time.
*/
public boolean isReadable(long txTimestamp);
/**
* Returns <code>true</code> if the enclosed value can be replaced with one of the given version by a
* transaction started at the given time.
*/
public boolean isWriteable(long txTimestamp, Object version, Comparator versionComparator);
/**
* Returns the enclosed value.
*/
public Object getValue();
/**
* Returns <code>true</code> if the given lock can be unlocked using the given SoftLock instance as a handle.
*/
public boolean isUnlockable(SoftLock lock);
/**
* Locks this entry, stamping it with the UUID and lockId given, with the lock timeout occuring at the specified
* time. The returned Lock object can be used to unlock the entry in the future.
*/
public Lock lock(long timeout, UUID uuid, long lockId);
}
/**
* Wrapper type representing unlocked items.
*/
protected static final class Item implements Serializable, Lockable {
private static final long serialVersionUID = 1L;
private final Object value;
private final Object version;
private final long timestamp;
private final long itemId;
/**
* Creates an unlocked item wrapping the given value with a version and creation timestamp.
*/
Item(Object value, Object version, long timestamp, long itemId) {
this.value = value;
this.version = version;
this.timestamp = timestamp;
this.itemId = itemId;
}
@Override
public boolean isReadable(long txTimestamp) {
return txTimestamp > timestamp;
}
@Override
@SuppressWarnings("unchecked")
public boolean isWriteable(long txTimestamp, Object newVersion, Comparator versionComparator) {
return version != null && versionComparator.compare( version, newVersion ) < 0;
}
@Override
public Object getValue() {
return value;
}
@Override
public boolean isUnlockable(SoftLock lock) {
return false;
}
@Override
public Lock lock(long timeout, UUID uuid, long lockId) {
return new Lock( timeout, uuid, lockId, version );
}
@Override
public boolean equals(Object obj) {
if (obj == this) {
return true;
}
else if (obj instanceof Item) {
return itemId == ((Item) obj).itemId;
}
else {
return false;
}
}
@Override
public int hashCode() {
return Long.hashCode( itemId );
}
@Override
public String toString() {
return "Item{" +
"value=" + value +
", version=" + version +
", timestamp=" + timestamp +
'}';
}
}
/**
* Wrapper type representing locked items.
*/
public static final class Lock implements Serializable, Lockable {
private static final long serialVersionUID = 2L;
private final UUID sourceUuid;
private final long lockId;
private final Object version;
private final long timeout;
private final boolean concurrent;
private final int multiplicity;
private final long unlockTimestamp;
/**
* Creates a locked item with the given identifiers and object version.
*/
public Lock(long timeout, UUID sourceUuid, long lockId, Object version) {
this(timeout, sourceUuid, lockId, version, 0, 1, false);
}
private Lock(long timeout, UUID sourceUuid, long lockId, Object version,
long unlockTimestamp, int multiplicity, boolean concurrent) {
this.sourceUuid = sourceUuid;
this.lockId = lockId;
this.version = version;
this.timeout = timeout;
this.unlockTimestamp = unlockTimestamp;
this.multiplicity = multiplicity;
this.concurrent = concurrent;
}
@Override
public boolean isReadable(long txTimestamp) {
return false;
}
@Override
@SuppressWarnings({ "SimplifiableIfStatement", "unchecked" })
public boolean isWriteable(long txTimestamp, Object newVersion, Comparator versionComparator) {
if ( txTimestamp > timeout ) {
// if timedout then allow write
return true;
}
if ( multiplicity > 0 ) {
// if still locked then disallow write
return false;
}
return version == null
? txTimestamp > unlockTimestamp
: versionComparator.compare( version, newVersion ) < 0;
}
@Override
public Object getValue() {
return null;
}
@Override
public boolean isUnlockable(SoftLock lock) {
if ( lock == this ) {
return true;
}
else if ( lock instanceof Lock ) {
return (lockId == ((Lock) lock).lockId) && sourceUuid.equals(((Lock) lock).sourceUuid);
}
else {
return false;
}
}
@Override
@SuppressWarnings("SimplifiableIfStatement")
public boolean equals(Object o) {
if ( o == this ) {
return true;
}
else if ( o instanceof Lock ) {
return (lockId == ((Lock)o ).lockId) && sourceUuid.equals( ( (Lock) o ).sourceUuid )
&& (multiplicity == ((Lock) o).multiplicity);
}
else {
return false;
}
}
@Override
public int hashCode() {
final int hash = ( sourceUuid != null ? sourceUuid.hashCode() : 0 );
return hash ^ Long.hashCode( lockId );
}
/**
* Returns true if this Lock has been concurrently locked by more than one transaction.
*/
public boolean wasLockedConcurrently() {
return concurrent;
}
@Override
public Lock lock(long timeout, UUID uuid, long lockId) {
return new Lock( timeout, this.sourceUuid, this.lockId, this.version,
0, this.multiplicity + 1, true );
}
/**
* Unlocks this Lock, and timestamps the unlock event.
*/
public Lock unlock(long timestamp) {
if (multiplicity == 1) {
return new Lock(timeout, sourceUuid, lockId, version,
timestamp, 0, concurrent );
}
else {
return new Lock(timeout, sourceUuid, lockId, version,
0, multiplicity - 1, concurrent );
}
}
@Override
public String toString() {
return "Lock Source-UUID:" + sourceUuid + " Lock-ID:" + lockId;
}
}
}

View File

@ -1,95 +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.access;
import org.hibernate.boot.spi.SessionFactoryOptions;
import org.hibernate.cache.CacheException;
import org.hibernate.cache.jcache.JCacheTransactionalDataRegion;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
/**
* @author Alex Snaps
*/
abstract class JCacheRegionAccessStrategy<R extends JCacheTransactionalDataRegion> implements RegionAccessStrategy {
private final R region;
public JCacheRegionAccessStrategy(R region) {
if ( region == null ) {
throw new NullPointerException( "Requires a non-null JCacheTransactionalDataRegion" );
}
this.region = region;
}
@Override
public Object get(SharedSessionContractImplementor session, Object key, long txTimestamp) throws CacheException {
return region.get( key );
}
@Override
public boolean putFromLoad(SharedSessionContractImplementor session, Object key, Object value, long txTimestamp, Object version) throws CacheException {
final SessionFactoryOptions options = region.getSessionFactoryOptions();
final boolean minimalPutOverride = options != null && options.isMinimalPutsEnabled();
return putFromLoad( session, key, value, txTimestamp, version, minimalPutOverride );
}
@Override
public boolean putFromLoad(SharedSessionContractImplementor session, Object key, Object value, long txTimestamp, Object version, boolean minimalPutOverride)
throws CacheException {
if ( minimalPutOverride && region.contains( key ) ) {
return false;
}
else {
region.put( key, value );
return true;
}
}
@Override
public SoftLock lockItem(SharedSessionContractImplementor session, Object key, Object version) throws CacheException {
return null;
}
@Override
public SoftLock lockRegion() throws CacheException {
return null;
}
@Override
public void unlockItem(SharedSessionContractImplementor session, Object key, SoftLock lock) throws CacheException {
evict( key );
}
@Override
public void unlockRegion(SoftLock lock) throws CacheException {
evictAll();
}
@Override
public void remove(SharedSessionContractImplementor session, Object key) throws CacheException {
// jcache only supports asynchronous access strategies
}
@Override
public void removeAll() throws CacheException {
evictAll();
}
@Override
public void evict(Object key) throws CacheException {
region.remove( key );
}
@Override
public void evictAll() throws CacheException {
region.clear();
}
public R getRegion() {
return region;
}
}

View File

@ -1,43 +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.access;
import org.hibernate.cache.CacheException;
import org.hibernate.cache.internal.DefaultCacheKeysFactory;
import org.hibernate.cache.jcache.JCacheCollectionRegion;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.persister.collection.CollectionPersister;
/**
* @author Alex Snaps
*/
public class NonStrictCollectionRegionAccessStrategy
extends JCacheRegionAccessStrategy<JCacheCollectionRegion>
implements CollectionRegionAccessStrategy {
public NonStrictCollectionRegionAccessStrategy(JCacheCollectionRegion jCacheCollectionRegion) {
super( jCacheCollectionRegion );
}
@Override
public Object generateCacheKey(Object id, CollectionPersister persister, SessionFactoryImplementor factory, String tenantIdentifier) {
return DefaultCacheKeysFactory.staticCreateCollectionKey( id, persister, factory, tenantIdentifier );
}
@Override
public Object getCacheKeyId(Object cacheKey) {
return DefaultCacheKeysFactory.staticGetCollectionId( cacheKey );
}
@Override
public void remove(SharedSessionContractImplementor session, Object key) throws CacheException {
evict( key );
}
}

View File

@ -1,66 +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.access;
import org.hibernate.cache.CacheException;
import org.hibernate.cache.internal.DefaultCacheKeysFactory;
import org.hibernate.cache.jcache.JCacheEntityRegion;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.persister.entity.EntityPersister;
/**
* @author Alex Snaps
*/
public class NonStrictEntityRegionAccessStrategy extends JCacheRegionAccessStrategy<JCacheEntityRegion>
implements EntityRegionAccessStrategy {
public NonStrictEntityRegionAccessStrategy(JCacheEntityRegion jCacheEntityRegion) {
super( jCacheEntityRegion );
}
@Override
public boolean insert(SharedSessionContractImplementor session, Object key, Object value, Object version) throws CacheException {
return false;
}
@Override
public boolean afterInsert(SharedSessionContractImplementor session, Object key, Object value, Object version) throws CacheException {
getRegion().put( key, value );
return true;
}
@Override
public boolean update(SharedSessionContractImplementor session, Object key, Object value, Object currentVersion, Object previousVersion)
throws CacheException {
getRegion().remove( key );
return false;
}
@Override
public boolean afterUpdate(SharedSessionContractImplementor session, Object key, Object value, Object currentVersion, Object previousVersion, SoftLock lock)
throws CacheException {
getRegion().remove( key );
return false;
}
@Override
public Object generateCacheKey(Object id, EntityPersister persister, SessionFactoryImplementor factory, String tenantIdentifier) {
return DefaultCacheKeysFactory.staticCreateEntityKey( id, persister, factory, tenantIdentifier );
}
@Override
public Object getCacheKeyId(Object cacheKey) {
return DefaultCacheKeysFactory.staticGetEntityId( cacheKey );
}
@Override
public void remove(SharedSessionContractImplementor session, Object key) throws CacheException {
evict( key );
}
}

View File

@ -1,58 +0,0 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
*/
package org.hibernate.cache.jcache.access;
import org.hibernate.cache.CacheException;
import org.hibernate.cache.internal.DefaultCacheKeysFactory;
import org.hibernate.cache.jcache.JCacheNaturalIdRegion;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.persister.entity.EntityPersister;
/**
* @author Alex Snaps
*/
public class NonStrictNaturalIdRegionAccessStrategy
extends JCacheRegionAccessStrategy<JCacheNaturalIdRegion>
implements NaturalIdRegionAccessStrategy {
public NonStrictNaturalIdRegionAccessStrategy(JCacheNaturalIdRegion jCacheNaturalIdRegion) {
super( jCacheNaturalIdRegion );
}
@Override
public boolean insert(SharedSessionContractImplementor session, Object key, Object value) throws CacheException {
return false;
}
@Override
public boolean afterInsert(SharedSessionContractImplementor session, Object key, Object value) throws CacheException {
return false;
}
@Override
public boolean update(SharedSessionContractImplementor session, Object key, Object value) throws CacheException {
remove( session, key );
return false;
}
@Override
public boolean afterUpdate(SharedSessionContractImplementor session, Object key, Object value, SoftLock lock) throws CacheException {
unlockItem( session, key, lock );
return false;
}
@Override
public Object generateCacheKey(Object[] naturalIdValues, EntityPersister persister, SharedSessionContractImplementor session) {
return DefaultCacheKeysFactory.staticCreateNaturalIdKey( naturalIdValues, persister, session );
}
@Override
public Object[] getNaturalIdValues(Object cacheKey) {
return DefaultCacheKeysFactory.staticGetNaturalIdValues( cacheKey );
}
}

View File

@ -1,35 +0,0 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
*/
package org.hibernate.cache.jcache.access;
import org.hibernate.cache.internal.DefaultCacheKeysFactory;
import org.hibernate.cache.jcache.JCacheCollectionRegion;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.persister.collection.CollectionPersister;
/**
* @author Alex Snaps
*/
public class ReadOnlyCollectionRegionAccessStrategy
extends JCacheRegionAccessStrategy<JCacheCollectionRegion>
implements CollectionRegionAccessStrategy {
public ReadOnlyCollectionRegionAccessStrategy(JCacheCollectionRegion jCacheCollectionRegion) {
super( jCacheCollectionRegion );
}
@Override
public Object generateCacheKey(Object id, CollectionPersister persister, SessionFactoryImplementor factory, String tenantIdentifier) {
return DefaultCacheKeysFactory.staticCreateCollectionKey( id, persister, factory, tenantIdentifier );
}
@Override
public Object getCacheKeyId(Object cacheKey) {
return DefaultCacheKeysFactory.staticGetCollectionId( cacheKey );
}
}

View File

@ -1,58 +0,0 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
*/
package org.hibernate.cache.jcache.access;
import org.hibernate.cache.CacheException;
import org.hibernate.cache.internal.DefaultCacheKeysFactory;
import org.hibernate.cache.jcache.JCacheEntityRegion;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.persister.entity.EntityPersister;
/**
* @author Alex Snaps
*/
public class ReadOnlyEntityRegionAccessStrategy extends JCacheRegionAccessStrategy<JCacheEntityRegion>
implements EntityRegionAccessStrategy {
public ReadOnlyEntityRegionAccessStrategy(JCacheEntityRegion jCacheEntityRegion) {
super( jCacheEntityRegion );
}
@Override
public boolean insert(SharedSessionContractImplementor session, Object key, Object value, Object version) throws CacheException {
return false;
}
@Override
public boolean afterInsert(SharedSessionContractImplementor session, Object key, Object value, Object version) throws CacheException {
getRegion().put( key, value );
return true;
}
@Override
public boolean update(SharedSessionContractImplementor session, Object key, Object value, Object currentVersion, Object previousVersion)
throws CacheException {
throw new UnsupportedOperationException( "This is a ReadOnly strategy!" );
}
@Override
public boolean afterUpdate(SharedSessionContractImplementor session, Object key, Object value, Object currentVersion, Object previousVersion, SoftLock lock)
throws CacheException {
throw new UnsupportedOperationException( "This is a ReadOnly strategy!" );
}
@Override
public Object generateCacheKey(Object id, EntityPersister persister, SessionFactoryImplementor factory, String tenantIdentifier) {
return DefaultCacheKeysFactory.staticCreateEntityKey( id, persister, factory, tenantIdentifier );
}
@Override
public Object getCacheKeyId(Object cacheKey) {
return DefaultCacheKeysFactory.staticGetEntityId( cacheKey );
}
}

View File

@ -1,57 +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.access;
import org.hibernate.cache.CacheException;
import org.hibernate.cache.internal.DefaultCacheKeysFactory;
import org.hibernate.cache.jcache.JCacheNaturalIdRegion;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.persister.entity.EntityPersister;
/**
* @author Alex Snaps
*/
public class ReadOnlyNaturalIdRegionAccessStrategy
extends JCacheRegionAccessStrategy<JCacheNaturalIdRegion>
implements NaturalIdRegionAccessStrategy {
public ReadOnlyNaturalIdRegionAccessStrategy(JCacheNaturalIdRegion jCacheNaturalIdRegion) {
super( jCacheNaturalIdRegion );
}
@Override
public boolean insert(SharedSessionContractImplementor session, Object key, Object value) throws CacheException {
return false;
}
@Override
public boolean afterInsert(SharedSessionContractImplementor session, Object key, Object value) throws CacheException {
getRegion().put( key, value );
return true;
}
@Override
public boolean update(SharedSessionContractImplementor session, Object key, Object value) throws CacheException {
throw new UnsupportedOperationException( "This is a ReadOnly strategy!" );
}
@Override
public boolean afterUpdate(SharedSessionContractImplementor session, Object key, Object value, SoftLock lock) throws CacheException {
throw new UnsupportedOperationException( "This is a ReadOnly strategy!" );
}
@Override
public Object generateCacheKey(Object[] naturalIdValues, EntityPersister persister, SharedSessionContractImplementor session) {
return DefaultCacheKeysFactory.staticCreateNaturalIdKey( naturalIdValues, persister, session );
}
@Override
public Object[] getNaturalIdValues(Object cacheKey) {
return DefaultCacheKeysFactory.staticGetNaturalIdValues( cacheKey );
}
}

View File

@ -1,37 +0,0 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
*/
package org.hibernate.cache.jcache.access;
import org.hibernate.cache.internal.DefaultCacheKeysFactory;
import org.hibernate.cache.jcache.JCacheCollectionRegion;
import org.hibernate.cache.spi.access.CollectionDataAccess;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.persister.collection.CollectionPersister;
/**
* @author Alex Snaps
*/
public class ReadWriteCollectionRegionAccessStrategy
extends AbstractReadWriteRegionAccessStrategy<JCacheCollectionRegion>
implements CollectionDataAccess {
public ReadWriteCollectionRegionAccessStrategy(JCacheCollectionRegion jCacheCollectionRegion) {
super( jCacheCollectionRegion );
}
@Override
public Object generateCacheKey(Object id, CollectionPersister persister, SessionFactoryImplementor factory, String tenantIdentifier) {
return DefaultCacheKeysFactory.staticCreateCollectionKey( id, persister, factory, tenantIdentifier );
}
@Override
public Object getCacheKeyId(Object cacheKey) {
return DefaultCacheKeysFactory.staticGetCollectionId( cacheKey );
}
}

View File

@ -1,80 +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.access;
import org.hibernate.cache.CacheException;
import org.hibernate.cache.internal.DefaultCacheKeysFactory;
import org.hibernate.cache.jcache.JCacheEntityRegion;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.persister.entity.EntityPersister;
/**
* @author Alex Snaps
*/
public class ReadWriteEntityRegionAccessStrategy
extends AbstractReadWriteRegionAccessStrategy<JCacheEntityRegion>
implements EntityRegionAccessStrategy {
public ReadWriteEntityRegionAccessStrategy(JCacheEntityRegion region) {
super( region );
}
@Override
public boolean insert(SharedSessionContractImplementor session, Object key, Object value, Object version) throws CacheException {
return false;
}
@Override
public boolean afterInsert(SharedSessionContractImplementor session, Object key, Object value, Object version) throws CacheException {
return region.putIfAbsent( key, new Item(value, version, region.nextTimestamp(), nextItemId() ));
}
@Override
public boolean update(SharedSessionContractImplementor session, Object key, Object value, Object currentVersion, Object previousVersion)
throws CacheException {
return false;
}
@Override
public boolean afterUpdate(SharedSessionContractImplementor session, Object key, Object value, Object currentVersion, Object previousVersion, SoftLock lock)
throws CacheException {
while (true) {
Lockable item = (Lockable) region.get( key );
if ( item != null && item.isUnlockable( lock ) ) {
Lock lockItem = (Lock) item;
if ( lockItem.wasLockedConcurrently() ) {
if (region.replace( key, lockItem, lockItem.unlock( region.nextTimestamp() ))) {
return false;
}
}
else {
if (region.replace( key, lockItem, new Item(value, currentVersion, region.nextTimestamp(), nextItemId() ))) {
return true;
}
}
}
else {
handleMissingLock( key, item );
return false;
}
}
}
@Override
public Object generateCacheKey(Object id, EntityPersister persister, SessionFactoryImplementor factory, String tenantIdentifier) {
return DefaultCacheKeysFactory.staticCreateEntityKey( id, persister, factory, tenantIdentifier );
}
@Override
public Object getCacheKeyId(Object cacheKey) {
return DefaultCacheKeysFactory.staticGetEntityId( cacheKey );
}
}

View File

@ -1,79 +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.access;
import org.hibernate.cache.CacheException;
import org.hibernate.cache.internal.DefaultCacheKeysFactory;
import org.hibernate.cache.jcache.JCacheNaturalIdRegion;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.persister.entity.EntityPersister;
/**
* @author Alex Snaps
*/
public class ReadWriteNaturalIdRegionAccessStrategy
extends AbstractReadWriteRegionAccessStrategy<JCacheNaturalIdRegion>
implements NaturalIdRegionAccessStrategy {
public ReadWriteNaturalIdRegionAccessStrategy(JCacheNaturalIdRegion jCacheNaturalIdRegion) {
super ( jCacheNaturalIdRegion );
}
@Override
public boolean insert(SharedSessionContractImplementor session, Object key, Object value) throws CacheException {
return false;
}
@Override
public boolean afterInsert(SharedSessionContractImplementor session, Object key, Object value) throws CacheException {
return region.putIfAbsent( key, new Item( value, null, region.nextTimestamp(), nextItemId() ));
}
@Override
public boolean update(SharedSessionContractImplementor session, Object key, Object value)
throws CacheException {
return false;
}
@Override
public boolean afterUpdate(SharedSessionContractImplementor session, Object key, Object value, SoftLock lock)
throws CacheException {
while (true) {
Lockable item = (Lockable) region.get( key );
if ( item != null && item.isUnlockable( lock ) ) {
final Lock lockItem = (Lock) item;
if ( lockItem.wasLockedConcurrently() ) {
if (region.replace( key, lockItem, lockItem.unlock( region.nextTimestamp() ) )) {
return false;
}
}
else {
if (region.replace( key, lockItem, new Item(value, null, region.nextTimestamp(), nextItemId() ))) {
return true;
}
}
}
else {
handleMissingLock( key, item );
return false;
}
}
}
@Override
public Object generateCacheKey(Object[] naturalIdValues, EntityPersister persister, SharedSessionContractImplementor session) {
return DefaultCacheKeysFactory.staticCreateNaturalIdKey( naturalIdValues, persister, session );
}
@Override
public Object[] getNaturalIdValues(Object cacheKey) {
return DefaultCacheKeysFactory.staticGetNaturalIdValues( cacheKey );
}
}

View File

@ -1,11 +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>.
*/
/**
* Access strategies for the JSR-107 Hibernate caching provider.
*/
package org.hibernate.cache.jcache.access;

View File

@ -0,0 +1,25 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
*/
package org.hibernate.cache.jcache.internal;
import javax.cache.Cache;
import org.hibernate.cache.spi.support.DomainDataStorageAccess;
/**
* @author Steve Ebersole
*/
public class DomainDataJCacheAccessImpl extends JCacheAccessImpl implements DomainDataStorageAccess {
public DomainDataJCacheAccessImpl(Cache underlyingCache) {
super( underlyingCache );
}
@Override
public void putFromLoad(Object key, Object value) {
putIntoCache( key, value );
}
}

View File

@ -0,0 +1,205 @@
/*
* 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.CollectionDataCachingConfig;
import org.hibernate.cache.cfg.spi.DomainDataRegionBuildingContext;
import org.hibernate.cache.cfg.spi.DomainDataRegionConfig;
import org.hibernate.cache.cfg.spi.EntityDataCachingConfig;
import org.hibernate.cache.cfg.spi.NaturalIdDataCachingConfig;
import org.hibernate.cache.spi.CacheKeysFactory;
import org.hibernate.cache.spi.access.AccessType;
import org.hibernate.cache.spi.access.CollectionDataAccess;
import org.hibernate.cache.spi.access.EntityDataAccess;
import org.hibernate.cache.spi.access.NaturalIdDataAccess;
import org.hibernate.cache.spi.support.AbstractDomainDataRegion;
import org.hibernate.cache.spi.support.CollectionNonStrictReadWriteAccess;
import org.hibernate.cache.spi.support.CollectionReadOnlyAccess;
import org.hibernate.cache.spi.support.CollectionReadWriteAccess;
import org.hibernate.cache.spi.support.EntityNonStrictReadWriteAccess;
import org.hibernate.cache.spi.support.EntityReadOnlyAccess;
import org.hibernate.cache.spi.support.EntityReadWriteAccess;
import org.hibernate.cache.spi.support.NaturalIdNonStrictReadWriteAccess;
import org.hibernate.cache.spi.support.NaturalIdReadOnlyAccess;
import org.hibernate.cache.spi.support.NaturalIdReadWriteAccess;
import org.hibernate.metamodel.model.domain.NavigableRole;
import org.jboss.logging.Logger;
/**
* @author Steve Ebersole
*/
public class DomainDataRegionImpl extends AbstractDomainDataRegion {
private static final Logger log = Logger.getLogger( DomainDataRegionImpl.class );
private final CacheKeysFactory effectiveKeysFactory;
public DomainDataRegionImpl(
DomainDataRegionConfig regionConfig,
JCacheRegionFactory regionFactory,
Cache underlyingCache,
DomainDataRegionBuildingContext buildingContext) {
super(
regionConfig,
regionFactory,
new DomainDataJCacheAccessImpl( underlyingCache ),
buildingContext
);
this.effectiveKeysFactory = regionFactory.determineKeysFactoryToUse( buildingContext );
}
public CacheKeysFactory getEffectiveKeysFactory() {
return effectiveKeysFactory;
}
@Override
public EntityDataAccess generateEntityAccess(EntityDataCachingConfig entityAccessConfig) {
final NavigableRole namedEntityRole = entityAccessConfig.getNavigableRole();
final AccessType accessType = entityAccessConfig.getAccessType();
log.debugf( "Generating entity cache access [%s] : %s", accessType.getExternalName(), namedEntityRole );
switch ( accessType ) {
case READ_ONLY: {
return new EntityReadOnlyAccess(
this,
effectiveKeysFactory,
getStorageAccess(),
entityAccessConfig
);
}
case READ_WRITE: {
return new EntityReadWriteAccess(
this,
effectiveKeysFactory,
getStorageAccess(),
entityAccessConfig
);
}
case NONSTRICT_READ_WRITE: {
return new EntityNonStrictReadWriteAccess(
this,
effectiveKeysFactory,
getStorageAccess(),
entityAccessConfig
);
}
case TRANSACTIONAL: {
return generateTransactionalEntityDataAccess( this, entityAccessConfig );
}
default: {
throw new IllegalArgumentException( "Unrecognized cache AccessType - " + accessType );
}
}
}
protected EntityDataAccess generateTransactionalEntityDataAccess(
DomainDataRegionImpl domainDataRegion,
EntityDataCachingConfig entityAccessConfig) {
throw generateTransactionalNotSupportedException();
}
private UnsupportedOperationException generateTransactionalNotSupportedException() {
return new UnsupportedOperationException( "Cache provider [" + getRegionFactory() + "] does not support `" + AccessType.TRANSACTIONAL.getExternalName() + "` access" );
}
@Override
public NaturalIdDataAccess generateNaturalIdAccess(NaturalIdDataCachingConfig naturalIdDataCachingConfig) {
final NavigableRole namedEntityRole = naturalIdDataCachingConfig.getNavigableRole();
final AccessType accessType = naturalIdDataCachingConfig.getAccessType();
log.debugf( "Generating entity natural-id access [%s] : %s", accessType.getExternalName(), namedEntityRole );
switch ( accessType ) {
case READ_ONLY: {
return new NaturalIdReadOnlyAccess(
this,
effectiveKeysFactory,
getStorageAccess(),
naturalIdDataCachingConfig
);
}
case READ_WRITE: {
return new NaturalIdReadWriteAccess(
this,
effectiveKeysFactory,
getStorageAccess(),
naturalIdDataCachingConfig
);
}
case NONSTRICT_READ_WRITE: {
return new NaturalIdNonStrictReadWriteAccess(
this,
effectiveKeysFactory,
getStorageAccess(),
naturalIdDataCachingConfig
);
}
case TRANSACTIONAL: {
return generateTransactionalNaturalIdDataAccess( this, naturalIdDataCachingConfig );
}
default: {
throw new IllegalArgumentException( "Unrecognized cache AccessType - " + accessType );
}
}
}
protected NaturalIdDataAccess generateTransactionalNaturalIdDataAccess(
DomainDataRegionImpl domainDataRegion,
NaturalIdDataCachingConfig config) {
throw generateTransactionalNotSupportedException();
}
@Override
public CollectionDataAccess generateCollectionAccess(CollectionDataCachingConfig config) {
final NavigableRole namedCollectionRole = config.getNavigableRole();
log.debugf( "Generating collection cache access : %s", namedCollectionRole );
switch ( config.getAccessType() ) {
case READ_ONLY: {
return new CollectionReadOnlyAccess(
this,
effectiveKeysFactory,
getStorageAccess(),
config
);
}
case READ_WRITE: {
return new CollectionReadWriteAccess(
this,
effectiveKeysFactory,
getStorageAccess(),
config
);
}
case NONSTRICT_READ_WRITE: {
return new CollectionNonStrictReadWriteAccess(
this,
effectiveKeysFactory,
getStorageAccess(),
config
);
}
case TRANSACTIONAL: {
return generateTransactionalCollectionDataAccess( this, config );
}
default: {
throw new IllegalArgumentException( "Unrecognized cache AccessType - " + config.getAccessType() );
}
}
}
protected CollectionDataAccess generateTransactionalCollectionDataAccess(
DomainDataRegionImpl domainDataRegion,
CollectionDataCachingConfig entityAccessConfig) {
throw generateTransactionalNotSupportedException();
}
}

View File

@ -0,0 +1,55 @@
/*
* 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.StorageAccess;
/**
* @author Steve Ebersole
*/
@SuppressWarnings("unchecked")
public class JCacheAccessImpl implements StorageAccess {
// todo (5.3) : consider RegionFactory support in hibernate-core based on StorageAccess
// plus the DomainDataStorageAccess defined here
private final Cache underlyingCache;
public JCacheAccessImpl(Cache underlyingCache) {
this.underlyingCache = underlyingCache;
}
public Cache getUnderlyingCache() {
return underlyingCache;
}
@Override
public Object getFromCache(Object key) {
return underlyingCache.get( key );
}
@Override
public void putIntoCache(Object key, Object value) {
underlyingCache.put( key, value );
}
@Override
public void removeFromCache(Object key) {
underlyingCache.remove( key );
}
@Override
public void clearCache() {
underlyingCache.clear();
}
@Override
public void release() {
underlyingCache.close();
}
}

View File

@ -1,15 +1,16 @@
/*
* 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>.
* 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;
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.internal.CoreMessageLogger;
import static org.jboss.logging.Logger.Level.ERROR;
@ -44,5 +45,5 @@ public interface JCacheMessageLogger extends CoreMessageLogger {
+ " out of balance lock/unlock sequences, or an eagerly evicting cache.",
id = NAMESPACE + 3
)
void missingLock(JCacheRegion region, Object key, Object value);
void missingLock(Region region, Object key, Object value);
}

View File

@ -0,0 +1,239 @@
/*
* 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 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;
import javax.cache.spi.CachingProvider;
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.SimpleTimestamper;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.jboss.logging.Logger;
/**
* @author Alex Snaps
*/
public class JCacheRegionFactory implements RegionFactory {
private static final String PROP_PREFIX = "hibernate.javax.cache";
public static final String PROVIDER = PROP_PREFIX + ".provider";
public static final String CONFIG_URI = PROP_PREFIX + ".uri";
private static final JCacheMessageLogger LOG = Logger.getMessageLogger(
JCacheMessageLogger.class,
JCacheRegionFactory.class.getName()
);
private final AtomicBoolean started = new AtomicBoolean( false );
private final CacheKeysFactory cacheKeysFactory;
private volatile CacheManager cacheManager;
private SessionFactoryOptions options;
public JCacheRegionFactory() {
this( DefaultCacheKeysFactory.INSTANCE );
}
public JCacheRegionFactory(CacheKeysFactory cacheKeysFactory) {
this.cacheKeysFactory = cacheKeysFactory;
}
protected CacheManager getCacheManager() {
return cacheManager;
}
public CacheKeysFactory determineKeysFactoryToUse(DomainDataRegionBuildingContext buildingContext) {
return buildingContext.getEnforcedCacheKeysFactory() != null
? buildingContext.getEnforcedCacheKeysFactory()
: cacheKeysFactory;
}
@Override
public boolean isMinimalPutsEnabledByDefault() {
return true;
}
@Override
public AccessType getDefaultAccessType() {
return AccessType.READ_WRITE;
}
@Override
public long nextTimestamp() {
return SimpleTimestamper.next();
}
@Override
public long getTimeout() {
return SimpleTimestamper.timeOut();
}
@Override
public void start(SessionFactoryOptions settings, Map configValues) throws CacheException {
if ( started.compareAndSet( false, true ) ) {
synchronized ( this ) {
this.options = options;
try {
this.cacheManager = getCacheManager( configValues );
}
finally {
if ( this.cacheManager == null ) {
started.set( false );
}
}
}
}
else {
LOG.attemptToRestartAlreadyStartedJCacheProvider();
}
}
@Override
public void stop() {
if ( started.compareAndSet( true, false ) ) {
synchronized ( this ) {
cacheManager.close();
cacheManager = null;
}
}
else {
LOG.attemptToRestopAlreadyStoppedJCacheProvider();
}
}
@Override
public String qualify(String regionName) {
return RegionNameQualifier.INSTANCE.qualify( regionName, getOptions() );
}
@Override
public QueryResultsRegion buildQueryResultsRegion(
String regionName,
SessionFactoryImplementor sessionFactory) {
return new QueryResultsRegionImpl(
regionName,
this,
getOrCreateCache( qualify( regionName ) )
);
}
@Override
public TimestampsRegion buildTimestampsRegion(
String regionName,
SessionFactoryImplementor sessionFactory) {
return new TimestampsRegionImpl(
regionName,
this,
getOrCreateCache( qualify( regionName ) )
);
}
@Override
public DomainDataRegion buildDomainDataRegion(
DomainDataRegionConfig regionConfig,
DomainDataRegionBuildingContext buildingContext) {
return new DomainDataRegionImpl(
regionConfig,
this,
getOrCreateCache( qualify( regionConfig.getRegionName() ) ),
buildingContext
);
}
boolean isStarted() {
return started.get() && cacheManager != null;
}
protected SessionFactoryOptions getOptions() {
return options;
}
protected CachingProvider getCachingProvider(final Map properties){
final CachingProvider cachingProvider;
final String provider = getProp( properties, PROVIDER );
if ( provider != null ) {
cachingProvider = Caching.getCachingProvider( provider );
}
else {
cachingProvider = Caching.getCachingProvider();
}
return cachingProvider;
}
protected CacheManager getCacheManager(final Map properties){
final CachingProvider cachingProvider = getCachingProvider( properties );
final CacheManager cacheManager;
final String cacheManagerUri = getProp( properties, CONFIG_URI );
if ( cacheManagerUri != null ) {
URI uri;
try {
uri = new URI( cacheManagerUri );
}
catch ( URISyntaxException e ) {
throw new CacheException( "Couldn't create URI from " + cacheManagerUri, e );
}
cacheManager = cachingProvider.getCacheManager( uri, cachingProvider.getDefaultClassLoader() );
}
else {
cacheManager = cachingProvider.getCacheManager();
}
return cacheManager;
}
protected Cache<Object, Object> getOrCreateCache(String qualifiedRegionName) {
checkStatus();
assert isQualified( qualifiedRegionName );
final Cache<Object, Object> cache = cacheManager.getCache( qualifiedRegionName );
if ( cache == null ) {
return createCache( qualifiedRegionName );
}
return cache;
}
private boolean isQualified(String regionName) {
final String prefix = options.getCacheRegionPrefix();
if ( prefix == null ) {
return true;
}
else {
return regionName.startsWith( prefix );
}
}
protected Cache<Object, Object> createCache(String regionName) {
throw new CacheException( "On-the-fly creation of JCache Cache objects is not supported" );
}
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!" );
}
}
}

View File

@ -0,0 +1,26 @@
/*
* 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.AbstractRegion;
import org.hibernate.cache.spi.QueryResultsRegion;
/**
* @author Chris Dennis
* @author Alex Snaps
* @author Steve Ebersole
*/
public class QueryResultsRegionImpl extends AbstractRegion implements QueryResultsRegion {
public QueryResultsRegionImpl(
String name,
JCacheRegionFactory regionFactory,
Cache cache) {
super( name, regionFactory, new JCacheAccessImpl( cache ) );
}
}

View File

@ -0,0 +1,45 @@
/*
* 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 java.util.ArrayList;
import java.util.List;
import org.hibernate.boot.registry.selector.SimpleStrategyRegistrationImpl;
import org.hibernate.boot.registry.selector.StrategyRegistration;
import org.hibernate.boot.registry.selector.StrategyRegistrationProvider;
import org.hibernate.cache.jcache.ConfigSettings;
import org.hibernate.cache.spi.RegionFactory;
/**
* Makes the JCache RegionFactory available to the Hibernate
* {@link org.hibernate.boot.registry.selector.spi.StrategySelector} service
* under a number of keys. Prefer to use
*
* @author Steve Ebersole
*/
public class StrategyRegistrationProviderImpl implements StrategyRegistrationProvider {
@Override
@SuppressWarnings("unchecked")
public Iterable<StrategyRegistration> getStrategyRegistrations() {
final List<StrategyRegistration> strategyRegistrations = new ArrayList<StrategyRegistration>();
strategyRegistrations.add(
new SimpleStrategyRegistrationImpl(
RegionFactory.class,
JCacheRegionFactory.class,
ConfigSettings.SIMPLE_FACTORY_NAME,
JCacheRegionFactory.class.getName(),
JCacheRegionFactory.class.getSimpleName(),
// legacy impl class name
"org.hibernate.cache.jcache.JCacheRegionFactory"
)
);
return strategyRegistrations;
}
}

View File

@ -0,0 +1,32 @@
/*
* 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.AbstractRegion;
/**
* A timestamps region specific wrapper around an Ehcache instance.
*
* @author Chris Dennis
* @author Abhishek Sanoujam
* @author Alex Snaps
*/
public class TimestampsRegionImpl extends AbstractRegion implements TimestampsRegion {
public TimestampsRegionImpl(
String regionName,
JCacheRegionFactory regionFactory,
Cache cache) {
super(
regionName,
regionFactory,
new JCacheAccessImpl( cache )
);
}
}

View File

@ -0,0 +1,8 @@
#
# Hibernate, Relational Persistence for Idiomatic Java
#
# License: GNU Lesser General Public License (LGPL), version 2.1 or later
# See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
#
org.hibernate.cache.jcache.internal.StrategyRegistrationProviderImpl

View File

@ -16,6 +16,7 @@
import org.junit.Test;
import org.hibernate.cache.CacheException;
import org.hibernate.cache.jcache.internal.JCacheRegionFactory;
import org.hibernate.cache.spi.access.AccessType;
import static java.util.Collections.EMPTY_MAP;

View File

@ -6,8 +6,6 @@
*/
package org.hibernate.cache.jcache.access;
import org.hibernate.cache.jcache.JCacheTransactionalDataRegion;
/**
* @author Alex Snaps

View File

@ -19,7 +19,7 @@
<property name="cache.use_query_cache">true</property>
<property name="cache.use_second_level_cache">true</property>
<property name="cache.use_structured_entries">true</property>
<property name="cache.region.factory_class">org.hibernate.cache.jcache.JCacheRegionFactory</property>
<property name="cache.region.factory_class">jcache</property>
<property name="net.sf.ehcache.configurationResourceName">/hibernate-config/ehcache.xml</property>
<!-- Echo all executed SQL to stdout -->
<property name="show_sql">true</property>

View File

@ -1,62 +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.Map;
import java.util.concurrent.ConcurrentHashMap;
import org.hibernate.cache.spi.DirectAccessRegion;
/**
* @author Steve Ebersole
*/
public abstract class AbstractDirectAccessRegion
extends AbstractRegion
implements DirectAccessRegion, DirectAccessRegion.DataAccess {
private Map dataMap;
public AbstractDirectAccessRegion(String name) {
super( name );
}
@Override
public DataAccess getAccess() {
return this;
}
@Override
public Object getFromCache(Object key) {
if ( dataMap == null ) {
return null;
}
return dataMap.get( key );
}
@Override
@SuppressWarnings("unchecked")
public void addToCache(Object key, Object value) {
if ( dataMap == null ) {
dataMap = new ConcurrentHashMap();
}
dataMap.put( key, value );
}
@Override
public void removeFromCache(Object key) {
if ( dataMap != null ) {
dataMap.remove( key );
}
}
@Override
public void clearCache() {
if ( dataMap != null ) {
dataMap.clear();
}
}
}

View File

@ -1,23 +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.AbstractCacheTransactionSynchronization;
import org.hibernate.cache.spi.RegionFactory;
import org.jboss.logging.Logger;
/**
* @author Steve Ebersole
*/
class CacheTransactionSynchronizationImpl extends AbstractCacheTransactionSynchronization {
private static final Logger log = Logger.getLogger( CacheTransactionSynchronizationImpl.class );
CacheTransactionSynchronizationImpl(RegionFactory regionFactory) {
super( regionFactory );
}
}

View File

@ -15,14 +15,13 @@
import org.hibernate.cache.cfg.spi.DomainDataRegionConfig;
import org.hibernate.cache.internal.DefaultCacheKeysFactory;
import org.hibernate.cache.spi.CacheKeysFactory;
import org.hibernate.cache.spi.CacheTransactionSynchronization;
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.engine.spi.SessionFactoryImplementor;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.jboss.logging.Logger;
@ -38,6 +37,7 @@ public class CachingRegionFactory implements RegionFactory {
private final CacheKeysFactory cacheKeysFactory;
private Properties properties;
private SessionFactoryOptions options;
public CachingRegionFactory() {
this( DefaultCacheKeysFactory.INSTANCE, null );
@ -63,6 +63,7 @@ public CacheKeysFactory getCacheKeysFactory() {
@Override
public void start(SessionFactoryOptions settings, Map configValues) throws CacheException {
options = settings;
}
@Override
@ -82,6 +83,11 @@ public AccessType getDefaultAccessType() {
return AccessType.READ_WRITE;
}
@Override
public String qualify(String regionName) {
return RegionNameQualifier.INSTANCE.qualify( regionName, options );
}
@Override
public long nextTimestamp() {
// return System.currentTimeMillis();
@ -93,11 +99,6 @@ public long getTimeout() {
return Timestamper.ONE_MS * 60000;
}
@Override
public CacheTransactionSynchronization createTransactionContext(SharedSessionContractImplementor session) {
return new CacheTransactionSynchronizationImpl( this );
}
@Override
public DomainDataRegion buildDomainDataRegion(
DomainDataRegionConfig regionConfig,
@ -109,14 +110,14 @@ public DomainDataRegion buildDomainDataRegion(
public QueryResultsRegion buildQueryResultsRegion(
String regionName,
SessionFactoryImplementor sessionFactory) {
return new QueryResultsRegionImpl( regionName, sessionFactory );
return new QueryResultsRegionImpl( regionName, this );
}
@Override
public TimestampsRegion buildTimestampsRegion(
String regionName,
SessionFactoryImplementor sessionFactory) {
return new TimestampsRegionImpl( regionName, sessionFactory );
return new TimestampsRegionImpl( regionName, this );
}
}

View File

@ -7,14 +7,19 @@
package org.hibernate.testing.cache;
import org.hibernate.cache.cfg.spi.CollectionDataCachingConfig;
import org.hibernate.cache.spi.CacheKeysFactory;
import org.hibernate.cache.spi.DomainDataRegion;
import org.hibernate.cache.spi.support.AbstractCollectionDataAccess;
/**
* @author Steve Ebersole
*/
public class CollectionTransactionAccess extends BaseCollectionDataAccess {
public class CollectionTransactionAccess extends AbstractCollectionDataAccess {
public CollectionTransactionAccess(
DomainDataRegionImpl region,
DomainDataRegion region,
CacheKeysFactory keysFactory,
DomainDataStorageAccessImpl domainDataStorageAccess,
CollectionDataCachingConfig config) {
super( region );
super( region, keysFactory, domainDataStorageAccess, config );
}
}

View File

@ -11,15 +11,22 @@
import org.hibernate.cache.cfg.spi.DomainDataRegionConfig;
import org.hibernate.cache.cfg.spi.EntityDataCachingConfig;
import org.hibernate.cache.cfg.spi.NaturalIdDataCachingConfig;
import org.hibernate.cache.spi.AbstractDomainDataRegion;
import org.hibernate.cache.spi.support.AbstractDomainDataRegion;
import org.hibernate.cache.spi.CacheKeysFactory;
import org.hibernate.cache.spi.access.AccessType;
import org.hibernate.cache.spi.access.CollectionDataAccess;
import org.hibernate.cache.spi.access.EntityDataAccess;
import org.hibernate.cache.spi.access.NaturalIdDataAccess;
import org.hibernate.cache.spi.support.CollectionNonStrictReadWriteAccess;
import org.hibernate.cache.spi.support.CollectionReadOnlyAccess;
import org.hibernate.cache.spi.support.CollectionReadWriteAccess;
import org.hibernate.cache.spi.support.EntityNonStrictReadWriteAccess;
import org.hibernate.cache.spi.support.EntityReadOnlyAccess;
import org.hibernate.cache.spi.support.EntityReadWriteAccess;
import org.hibernate.cache.spi.support.NaturalIdNonStrictReadWriteAccess;
import org.hibernate.cache.spi.support.NaturalIdReadOnlyAccess;
import org.hibernate.cache.spi.support.NaturalIdReadWriteAccess;
import org.hibernate.metamodel.model.domain.NavigableRole;
import org.hibernate.persister.collection.CollectionPersister;
import org.hibernate.persister.entity.EntityPersister;
import org.jboss.logging.Logger;
@ -35,7 +42,7 @@ public DomainDataRegionImpl(
DomainDataRegionConfig regionConfig,
CachingRegionFactory regionFactory,
DomainDataRegionBuildingContext buildingContext) {
super( regionConfig, regionFactory, buildingContext );
super( regionConfig, regionFactory, new DomainDataStorageAccessImpl(), buildingContext );
this.effectiveKeysFactory = buildingContext.getEnforcedCacheKeysFactory() != null
? buildingContext.getEnforcedCacheKeysFactory()
@ -46,6 +53,7 @@ public CacheKeysFactory getEffectiveKeysFactory() {
return effectiveKeysFactory;
}
@Override
public EntityDataAccess generateEntityAccess(EntityDataCachingConfig entityAccessConfig) {
final NavigableRole namedEntityRole = entityAccessConfig.getNavigableRole();
@ -55,16 +63,36 @@ public EntityDataAccess generateEntityAccess(EntityDataCachingConfig entityAcces
switch ( accessType ) {
case READ_ONLY: {
return new EntityReadOnlyAccess( this, entityAccessConfig );
}
case TRANSACTIONAL: {
return new EntityTransactionalAccess( this, entityAccessConfig );
return new EntityReadOnlyAccess(
this,
effectiveKeysFactory,
new DomainDataStorageAccessImpl(),
entityAccessConfig
);
}
case READ_WRITE: {
return new EntityReadWriteAccess( this, entityAccessConfig );
return new EntityReadWriteAccess(
this,
effectiveKeysFactory,
new DomainDataStorageAccessImpl(),
entityAccessConfig
);
}
case NONSTRICT_READ_WRITE: {
return new EntityNonStrictReadWriteAccess( this, entityAccessConfig );
return new EntityNonStrictReadWriteAccess(
this,
effectiveKeysFactory,
new DomainDataStorageAccessImpl(),
entityAccessConfig
);
}
case TRANSACTIONAL: {
return new EntityTransactionalAccess(
this,
effectiveKeysFactory,
new DomainDataStorageAccessImpl(),
entityAccessConfig
);
}
default: {
throw new IllegalArgumentException( "Unrecognized cache AccessType - " + accessType );
@ -81,16 +109,36 @@ public NaturalIdDataAccess generateNaturalIdAccess(NaturalIdDataCachingConfig na
switch ( accessType ) {
case READ_ONLY: {
return new NaturalIdReadOnlyAccess( this, naturalIdDataCachingConfig );
}
case TRANSACTIONAL: {
return new NaturalIdTransactionalAccess( this, naturalIdDataCachingConfig );
return new NaturalIdReadOnlyAccess(
this,
effectiveKeysFactory,
new DomainDataStorageAccessImpl(),
naturalIdDataCachingConfig
);
}
case READ_WRITE: {
return new NaturalIdReadWriteAccess( this, naturalIdDataCachingConfig );
return new NaturalIdReadWriteAccess(
this,
effectiveKeysFactory,
new DomainDataStorageAccessImpl(),
naturalIdDataCachingConfig
);
}
case NONSTRICT_READ_WRITE: {
return new NaturalIdNonStrictReadWriteAccess( this, naturalIdDataCachingConfig );
return new NaturalIdNonStrictReadWriteAccess(
this,
effectiveKeysFactory,
new DomainDataStorageAccessImpl(),
naturalIdDataCachingConfig
);
}
case TRANSACTIONAL: {
return new NaturalIdTransactionalAccess(
this,
effectiveKeysFactory,
new DomainDataStorageAccessImpl(),
naturalIdDataCachingConfig
);
}
default: {
throw new IllegalArgumentException( "Unrecognized cache AccessType - " + accessType );
@ -106,16 +154,36 @@ public CollectionDataAccess generateCollectionAccess(CollectionDataCachingConfig
switch ( config.getAccessType() ) {
case READ_ONLY: {
return new CollectionReadOnlyAccess( this, config );
}
case TRANSACTIONAL: {
return new CollectionTransactionAccess( this, config );
return new CollectionReadOnlyAccess(
this,
effectiveKeysFactory,
new DomainDataStorageAccessImpl(),
config
);
}
case READ_WRITE: {
return new CollectionReadWriteAccess( this, config );
return new CollectionReadWriteAccess(
this,
effectiveKeysFactory,
new DomainDataStorageAccessImpl(),
config
);
}
case NONSTRICT_READ_WRITE: {
return new CollectionNonStrictReadWriteAccess( this, config );
return new CollectionNonStrictReadWriteAccess(
this,
effectiveKeysFactory,
new DomainDataStorageAccessImpl(),
config
);
}
case TRANSACTIONAL: {
return new CollectionTransactionAccess(
this,
effectiveKeysFactory,
new DomainDataStorageAccessImpl(),
config
);
}
default: {
throw new IllegalArgumentException( "Unrecognized cache AccessType - " + config.getAccessType() );

View File

@ -6,15 +6,14 @@
*/
package org.hibernate.testing.cache;
import org.hibernate.cache.cfg.spi.CollectionDataCachingConfig;
import org.hibernate.cache.spi.support.DomainDataStorageAccess;
/**
* @author Steve Ebersole
*/
public class CollectionReadOnlyAccess extends BaseCollectionDataAccess {
public CollectionReadOnlyAccess(
DomainDataRegionImpl region,
CollectionDataCachingConfig config) {
super( region );
public class DomainDataStorageAccessImpl extends StorageAcccessImpl implements DomainDataStorageAccess {
@Override
public void putFromLoad(Object key, Object value) {
getOrMakeDataMap().put( key, value );
}
}

View File

@ -7,15 +7,22 @@
package org.hibernate.testing.cache;
import org.hibernate.cache.cfg.spi.EntityDataCachingConfig;
import org.hibernate.cache.spi.CacheKeysFactory;
import org.hibernate.cache.spi.DomainDataRegion;
import org.hibernate.cache.spi.access.SoftLock;
import org.hibernate.cache.spi.support.AbstractEntityDataAccess;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
/**
* @author Steve Ebersole
*/
public class EntityTransactionalAccess extends BaseEntityDataAccess {
public EntityTransactionalAccess(DomainDataRegionImpl region, EntityDataCachingConfig entityAccessConfig) {
super( region );
public class EntityTransactionalAccess extends AbstractEntityDataAccess {
public EntityTransactionalAccess(
DomainDataRegion region,
CacheKeysFactory keysFactory,
DomainDataStorageAccessImpl domainDataStorageAccess,
EntityDataCachingConfig entityAccessConfig) {
super( region, keysFactory, domainDataStorageAccess );
}
@Override

View File

@ -1,30 +0,0 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
*/
package org.hibernate.testing.cache;
import org.hibernate.cache.cfg.spi.NaturalIdDataCachingConfig;
import org.hibernate.cache.spi.access.SoftLock;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
/**
* @author Steve Ebersole
*/
public class NaturalIdReadOnlyAccess extends BaseNaturalIdDataAccess {
public NaturalIdReadOnlyAccess(
DomainDataRegionImpl region,
NaturalIdDataCachingConfig naturalIdDataCachingConfig) {
super( region );
}
@Override
public void unlockItem(
SharedSessionContractImplementor session,
Object key,
SoftLock lock) {
evict( key );
}
}

View File

@ -7,14 +7,19 @@
package org.hibernate.testing.cache;
import org.hibernate.cache.cfg.spi.NaturalIdDataCachingConfig;
import org.hibernate.cache.spi.CacheKeysFactory;
import org.hibernate.cache.spi.DomainDataRegion;
import org.hibernate.cache.spi.support.AbstractNaturalIdDataAccess;
/**
* @author Steve Ebersole
*/
public class NaturalIdTransactionalAccess extends BaseNaturalIdDataAccess {
public class NaturalIdTransactionalAccess extends AbstractNaturalIdDataAccess {
public NaturalIdTransactionalAccess(
DomainDataRegionImpl region,
NaturalIdDataCachingConfig naturalIdDataCachingConfig) {
super( region );
DomainDataRegion region,
CacheKeysFactory keysFactory,
DomainDataStorageAccessImpl domainDataStorageAccess,
NaturalIdDataCachingConfig config) {
super( region, keysFactory, domainDataStorageAccess, config );
}
}

View File

@ -8,21 +8,15 @@
import org.hibernate.cache.spi.QueryResultsRegion;
import org.hibernate.cache.spi.RegionFactory;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.cache.spi.support.AbstractRegion;
/**
* @author Steve Ebersole
*/
class QueryResultsRegionImpl extends AbstractDirectAccessRegion implements QueryResultsRegion {
private final SessionFactoryImplementor sessionFactory;
QueryResultsRegionImpl(String name, SessionFactoryImplementor sessionFactory) {
super( name );
this.sessionFactory = sessionFactory;
}
@Override
public RegionFactory getRegionFactory() {
return sessionFactory.getCache().getRegionFactory();
public class QueryResultsRegionImpl extends AbstractRegion implements QueryResultsRegion {
public QueryResultsRegionImpl(
String name,
RegionFactory regionFactory) {
super( name, regionFactory, new StorageAcccessImpl() );
}
}

View File

@ -0,0 +1,63 @@
/*
* 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.Map;
import java.util.concurrent.ConcurrentHashMap;
import org.hibernate.cache.spi.support.StorageAccess;
/**
* @author Steve Ebersole
*/
public class StorageAcccessImpl implements StorageAccess {
private Map data;
@Override
public Object getFromCache(Object key) {
if ( data == null ) {
return null;
}
return data.get( key );
}
@Override
public void putIntoCache(Object key, Object value) {
getOrMakeDataMap().put( key, value );
}
protected Map getOrMakeDataMap() {
if ( data == null ) {
data = new ConcurrentHashMap();
}
return data;
}
@Override
public void removeFromCache(Object key) {
if ( data == null ) {
return;
}
data.remove( key );
}
@Override
public void clearCache() {
if ( data == null ) {
return;
}
data.clear();
}
@Override
public void release() {
clearCache();
data = null;
}
}

View File

@ -8,21 +8,15 @@
import org.hibernate.cache.spi.RegionFactory;
import org.hibernate.cache.spi.TimestampsRegion;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.cache.spi.support.AbstractRegion;
/**
* @author Steve Ebersole
*/
class TimestampsRegionImpl extends AbstractDirectAccessRegion implements TimestampsRegion {
private final SessionFactoryImplementor sessionFactory;
TimestampsRegionImpl(String regionName, SessionFactoryImplementor sessionFactory) {
super( regionName );
this.sessionFactory = sessionFactory;
}
@Override
public RegionFactory getRegionFactory() {
return sessionFactory.getCache().getRegionFactory();
public class TimestampsRegionImpl extends AbstractRegion implements TimestampsRegion {
public TimestampsRegionImpl(
String name,
RegionFactory regionFactory) {
super( name, regionFactory, new StorageAcccessImpl() );
}
}