mirror of
https://github.com/hibernate/hibernate-orm
synced 2025-02-21 18:45:09 +00:00
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:
parent
f432ecea68
commit
638ebf01df
@ -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"/>
|
||||
----
|
||||
====
|
||||
|
||||
|
@ -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(
|
||||
|
@ -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
|
||||
|
@ -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 {
|
||||
|
@ -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 );
|
||||
|
@ -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();
|
||||
}
|
||||
|
@ -36,7 +36,7 @@ public interface QueryResultRegionAccess extends QueryCache {
|
||||
*/
|
||||
@Override
|
||||
default void clear() throws CacheException {
|
||||
getRegion().getAccess().clearCache();
|
||||
getRegion().getStorageAccess().clearCache();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -13,8 +13,4 @@
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public interface QueryResultsRegion extends DirectAccessRegion {
|
||||
@Override
|
||||
default void clear() {
|
||||
getAccess().clearCache();
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
||||
}
|
||||
|
@ -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 );
|
||||
}
|
||||
}
|
@ -12,6 +12,6 @@
|
||||
public interface TimestampsRegion extends DirectAccessRegion {
|
||||
@Override
|
||||
default void clear() {
|
||||
getAccess().clearCache();
|
||||
getStorageAccess().clearCache();
|
||||
}
|
||||
}
|
||||
|
@ -95,7 +95,7 @@ public void accept(Serializable serializable) {
|
||||
|
||||
@Override
|
||||
default void clear() throws CacheException {
|
||||
getRegion().getAccess().clearCache();
|
||||
getRegion().getStorageAccess().clearCache();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
@ -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
|
@ -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();
|
||||
}
|
||||
|
||||
|
@ -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
|
@ -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 );
|
||||
}
|
||||
|
||||
|
@ -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()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
50
hibernate-core/src/main/java/org/hibernate/cache/spi/support/AbstractRegion.java
vendored
Normal file
50
hibernate-core/src/main/java/org/hibernate/cache/spi/support/AbstractRegion.java
vendored
Normal 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();
|
||||
}
|
||||
}
|
@ -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
|
27
hibernate-core/src/main/java/org/hibernate/cache/spi/support/CollectionReadOnlyAccess.java
vendored
Normal file
27
hibernate-core/src/main/java/org/hibernate/cache/spi/support/CollectionReadOnlyAccess.java
vendored
Normal 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 );
|
||||
}
|
||||
}
|
@ -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
|
14
hibernate-core/src/main/java/org/hibernate/cache/spi/support/DomainDataStorageAccess.java
vendored
Normal file
14
hibernate-core/src/main/java/org/hibernate/cache/spi/support/DomainDataStorageAccess.java
vendored
Normal 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);
|
||||
}
|
@ -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 );
|
||||
}
|
||||
|
||||
|
@ -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
|
@ -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
|
@ -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
|
41
hibernate-core/src/main/java/org/hibernate/cache/spi/support/NaturalIdReadOnlyAccess.java
vendored
Normal file
41
hibernate-core/src/main/java/org/hibernate/cache/spi/support/NaturalIdReadOnlyAccess.java
vendored
Normal 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 );
|
||||
}
|
||||
}
|
@ -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
|
18
hibernate-core/src/main/java/org/hibernate/cache/spi/support/RegionAccessType.java
vendored
Normal file
18
hibernate-core/src/main/java/org/hibernate/cache/spi/support/RegionAccessType.java
vendored
Normal 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
|
||||
}
|
36
hibernate-core/src/main/java/org/hibernate/cache/spi/support/RegionNameQualifier.java
vendored
Normal file
36
hibernate-core/src/main/java/org/hibernate/cache/spi/support/RegionNameQualifier.java
vendored
Normal file
@ -0,0 +1,36 @@
|
||||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
|
||||
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
|
||||
*/
|
||||
package org.hibernate.cache.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() {
|
||||
}
|
||||
}
|
@ -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() {
|
||||
}
|
||||
}
|
27
hibernate-core/src/main/java/org/hibernate/cache/spi/support/StorageAccess.java
vendored
Normal file
27
hibernate-core/src/main/java/org/hibernate/cache/spi/support/StorageAccess.java
vendored
Normal 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();
|
||||
|
||||
}
|
@ -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;
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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";
|
||||
}
|
@ -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() );
|
||||
}
|
||||
}
|
||||
}
|
@ -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");
|
||||
}
|
||||
}
|
@ -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();
|
||||
}
|
||||
|
||||
}
|
@ -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() );
|
||||
}
|
||||
}
|
||||
}
|
@ -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 );
|
||||
}
|
||||
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
@ -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!");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -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 );
|
||||
}
|
||||
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
@ -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 );
|
||||
}
|
||||
|
||||
}
|
@ -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 );
|
||||
}
|
||||
}
|
@ -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 );
|
||||
}
|
||||
}
|
@ -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 );
|
||||
}
|
||||
}
|
@ -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 );
|
||||
}
|
||||
}
|
@ -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 );
|
||||
}
|
||||
}
|
@ -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 );
|
||||
}
|
||||
|
||||
}
|
@ -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 );
|
||||
}
|
||||
}
|
@ -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 );
|
||||
}
|
||||
}
|
@ -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;
|
@ -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 );
|
||||
}
|
||||
}
|
205
hibernate-jcache/src/main/java/org/hibernate/cache/jcache/internal/DomainDataRegionImpl.java
vendored
Normal file
205
hibernate-jcache/src/main/java/org/hibernate/cache/jcache/internal/DomainDataRegionImpl.java
vendored
Normal 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();
|
||||
}
|
||||
}
|
55
hibernate-jcache/src/main/java/org/hibernate/cache/jcache/internal/JCacheAccessImpl.java
vendored
Normal file
55
hibernate-jcache/src/main/java/org/hibernate/cache/jcache/internal/JCacheAccessImpl.java
vendored
Normal 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();
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
239
hibernate-jcache/src/main/java/org/hibernate/cache/jcache/internal/JCacheRegionFactory.java
vendored
Normal file
239
hibernate-jcache/src/main/java/org/hibernate/cache/jcache/internal/JCacheRegionFactory.java
vendored
Normal 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!" );
|
||||
}
|
||||
}
|
||||
}
|
26
hibernate-jcache/src/main/java/org/hibernate/cache/jcache/internal/QueryResultsRegionImpl.java
vendored
Normal file
26
hibernate-jcache/src/main/java/org/hibernate/cache/jcache/internal/QueryResultsRegionImpl.java
vendored
Normal 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 ) );
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
32
hibernate-jcache/src/main/java/org/hibernate/cache/jcache/internal/TimestampsRegionImpl.java
vendored
Normal file
32
hibernate-jcache/src/main/java/org/hibernate/cache/jcache/internal/TimestampsRegionImpl.java
vendored
Normal 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 )
|
||||
);
|
||||
}
|
||||
}
|
@ -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
|
@ -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;
|
||||
|
@ -6,8 +6,6 @@
|
||||
*/
|
||||
package org.hibernate.cache.jcache.access;
|
||||
|
||||
import org.hibernate.cache.jcache.JCacheTransactionalDataRegion;
|
||||
|
||||
|
||||
/**
|
||||
* @author Alex Snaps
|
||||
|
@ -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>
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
@ -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 );
|
||||
}
|
||||
}
|
@ -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 );
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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 );
|
||||
}
|
||||
}
|
||||
|
@ -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() );
|
||||
|
@ -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 );
|
||||
}
|
||||
}
|
@ -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
|
||||
|
@ -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 );
|
||||
}
|
||||
}
|
@ -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 );
|
||||
}
|
||||
}
|
||||
|
@ -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() );
|
||||
}
|
||||
}
|
||||
|
63
hibernate-testing/src/main/java/org/hibernate/testing/cache/StorageAcccessImpl.java
vendored
Normal file
63
hibernate-testing/src/main/java/org/hibernate/testing/cache/StorageAcccessImpl.java
vendored
Normal 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;
|
||||
}
|
||||
}
|
@ -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() );
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user