HHH-10770 JCache 2nd-level cache
* Provider and CacheManager creation * Caches creation * Region class hierarchy * Different access strategies
This commit is contained in:
parent
030f442f3c
commit
a872885a43
|
@ -0,0 +1,20 @@
|
|||
dependencies {
|
||||
compile project( ':hibernate-core' )
|
||||
compile( libraries.jcache )
|
||||
|
||||
testCompile project( ':hibernate-testing' )
|
||||
testCompile( libraries.mockito )
|
||||
testRuntime( libraries.ehcache3 )
|
||||
}
|
||||
|
||||
def pomName() {
|
||||
return 'Hibernate/JCache Integration'
|
||||
}
|
||||
|
||||
def pomDescription() {
|
||||
return 'Integration for javax.cache into Hibernate as a second-level caching service'
|
||||
}
|
||||
|
||||
def osgiDescription() {
|
||||
return pomDescription()
|
||||
}
|
45
hibernate-jcache/src/main/java/org/hibernate/cache/jcache/JCacheCollectionRegion.java
vendored
Normal file
45
hibernate-jcache/src/main/java/org/hibernate/cache/jcache/JCacheCollectionRegion.java
vendored
Normal file
|
@ -0,0 +1,45 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
|
||||
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
||||
*/
|
||||
package org.hibernate.cache.jcache;
|
||||
|
||||
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.CacheDataDescription;
|
||||
import org.hibernate.cache.spi.CollectionRegion;
|
||||
import org.hibernate.cache.spi.access.AccessType;
|
||||
import org.hibernate.cache.spi.access.CollectionRegionAccessStrategy;
|
||||
|
||||
/**
|
||||
* @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() );
|
||||
}
|
||||
}
|
||||
}
|
50
hibernate-jcache/src/main/java/org/hibernate/cache/jcache/JCacheEntityRegion.java
vendored
Normal file
50
hibernate-jcache/src/main/java/org/hibernate/cache/jcache/JCacheEntityRegion.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.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.CacheDataDescription;
|
||||
import org.hibernate.cache.spi.EntityRegion;
|
||||
import org.hibernate.cache.spi.access.AccessType;
|
||||
import org.hibernate.cache.spi.access.EntityRegionAccessStrategy;
|
||||
|
||||
/**
|
||||
* @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");
|
||||
}
|
||||
}
|
44
hibernate-jcache/src/main/java/org/hibernate/cache/jcache/JCacheGeneralDataRegion.java
vendored
Normal file
44
hibernate-jcache/src/main/java/org/hibernate/cache/jcache/JCacheGeneralDataRegion.java
vendored
Normal file
|
@ -0,0 +1,44 @@
|
|||
/*
|
||||
* 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.cache.spi.GeneralDataRegion;
|
||||
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();
|
||||
}
|
||||
|
||||
}
|
39
hibernate-jcache/src/main/java/org/hibernate/cache/jcache/JCacheMessageLogger.java
vendored
Normal file
39
hibernate-jcache/src/main/java/org/hibernate/cache/jcache/JCacheMessageLogger.java
vendored
Normal file
|
@ -0,0 +1,39 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
|
||||
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
||||
*/
|
||||
package org.hibernate.cache.jcache;
|
||||
|
||||
import org.jboss.logging.annotations.LogMessage;
|
||||
import org.jboss.logging.annotations.Message;
|
||||
import org.jboss.logging.annotations.MessageLogger;
|
||||
|
||||
import org.hibernate.internal.CoreMessageLogger;
|
||||
|
||||
import static org.jboss.logging.Logger.Level.WARN;
|
||||
|
||||
/**
|
||||
* @author Alex Snaps
|
||||
*/
|
||||
@MessageLogger(projectCode = "HHH")
|
||||
public interface JCacheMessageLogger extends CoreMessageLogger {
|
||||
|
||||
static final int NAMESPACE = 40000;
|
||||
|
||||
@LogMessage(level = WARN)
|
||||
@Message(
|
||||
value = "Attempt to restart an already started JCacheRegionFactory. Use sessionFactory.close() between " +
|
||||
"repeated calls to buildSessionFactory. Using previously created JCacheRegionFactory.",
|
||||
id = NAMESPACE + 1
|
||||
)
|
||||
void attemptToRestartAlreadyStartedJCacheProvider();
|
||||
|
||||
@LogMessage(level = WARN)
|
||||
@Message(
|
||||
value = "Attempt to restop an already stopped JCacheRegionFactory.",
|
||||
id = NAMESPACE + 2
|
||||
)
|
||||
void attemptToRestopAlreadyStoppedJCacheProvider();
|
||||
}
|
45
hibernate-jcache/src/main/java/org/hibernate/cache/jcache/JCacheNaturalIdRegion.java
vendored
Normal file
45
hibernate-jcache/src/main/java/org/hibernate/cache/jcache/JCacheNaturalIdRegion.java
vendored
Normal file
|
@ -0,0 +1,45 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
|
||||
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
||||
*/
|
||||
package org.hibernate.cache.jcache;
|
||||
|
||||
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.CacheDataDescription;
|
||||
import org.hibernate.cache.spi.NaturalIdRegion;
|
||||
import org.hibernate.cache.spi.access.AccessType;
|
||||
import org.hibernate.cache.spi.access.NaturalIdRegionAccessStrategy;
|
||||
|
||||
/**
|
||||
* @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() );
|
||||
}
|
||||
}
|
||||
}
|
22
hibernate-jcache/src/main/java/org/hibernate/cache/jcache/JCacheQueryResultsRegion.java
vendored
Normal file
22
hibernate-jcache/src/main/java/org/hibernate/cache/jcache/JCacheQueryResultsRegion.java
vendored
Normal file
|
@ -0,0 +1,22 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
|
||||
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
||||
*/
|
||||
package org.hibernate.cache.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 );
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,73 @@
|
|||
/*
|
||||
* 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;
|
||||
}
|
||||
}
|
207
hibernate-jcache/src/main/java/org/hibernate/cache/jcache/JCacheRegionFactory.java
vendored
Normal file
207
hibernate-jcache/src/main/java/org/hibernate/cache/jcache/JCacheRegionFactory.java
vendored
Normal file
|
@ -0,0 +1,207 @@
|
|||
/*
|
||||
* 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.jboss.logging.Logger;
|
||||
|
||||
import org.hibernate.boot.spi.SessionFactoryOptions;
|
||||
import org.hibernate.cache.CacheException;
|
||||
import org.hibernate.cache.spi.CacheDataDescription;
|
||||
import org.hibernate.cache.spi.CollectionRegion;
|
||||
import org.hibernate.cache.spi.EntityRegion;
|
||||
import org.hibernate.cache.spi.NaturalIdRegion;
|
||||
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;
|
||||
|
||||
/**
|
||||
* @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 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 {
|
||||
final CachingProvider cachingProvider;
|
||||
final String provider = getProp( properties, PROVIDER );
|
||||
if ( provider != null ) {
|
||||
cachingProvider = Caching.getCachingProvider( provider );
|
||||
}
|
||||
else {
|
||||
cachingProvider = Caching.getCachingProvider();
|
||||
}
|
||||
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();
|
||||
}
|
||||
this.cacheManager = cacheManager;
|
||||
}
|
||||
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 Cache<Object, Object> getOrCreateCache(String regionName, Properties properties, CacheDataDescription metadata) {
|
||||
checkStatus();
|
||||
final Cache<Object, Object> cache = cacheManager.getCache( regionName );
|
||||
if ( cache == null ) {
|
||||
try {
|
||||
return cacheManager.createCache( regionName, newDefaultConfig( properties, metadata ) );
|
||||
}
|
||||
catch ( CacheException e ) {
|
||||
final Cache<Object, Object> existing = cacheManager.getCache( regionName );
|
||||
if ( existing != null ) {
|
||||
return existing;
|
||||
}
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
return cache;
|
||||
}
|
||||
|
||||
protected Configuration<Object, Object> newDefaultConfig(Properties properties, CacheDataDescription metadata) {
|
||||
return new MutableConfiguration<Object, Object>();
|
||||
}
|
||||
|
||||
CacheManager getCacheManager() {
|
||||
return cacheManager;
|
||||
}
|
||||
|
||||
static long nextTS() {
|
||||
return System.currentTimeMillis() / 100;
|
||||
}
|
||||
|
||||
static int timeOut() {
|
||||
return (int) (TimeUnit.SECONDS.toMillis(60) / 100);
|
||||
}
|
||||
|
||||
private String getProp(Properties properties, String prop) {
|
||||
return properties != null ? properties.getProperty( prop ) : null;
|
||||
}
|
||||
|
||||
private void checkStatus() {
|
||||
if(!isStarted()) {
|
||||
throw new IllegalStateException("JCacheRegionFactory not yet started!");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
22
hibernate-jcache/src/main/java/org/hibernate/cache/jcache/JCacheTimestampsRegion.java
vendored
Normal file
22
hibernate-jcache/src/main/java/org/hibernate/cache/jcache/JCacheTimestampsRegion.java
vendored
Normal file
|
@ -0,0 +1,22 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
|
||||
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
||||
*/
|
||||
package org.hibernate.cache.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 );
|
||||
}
|
||||
|
||||
}
|
78
hibernate-jcache/src/main/java/org/hibernate/cache/jcache/JCacheTransactionalDataRegion.java
vendored
Normal file
78
hibernate-jcache/src/main/java/org/hibernate/cache/jcache/JCacheTransactionalDataRegion.java
vendored
Normal file
|
@ -0,0 +1,78 @@
|
|||
/*
|
||||
* 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 javax.cache.processor.EntryProcessor;
|
||||
|
||||
import org.hibernate.boot.spi.SessionFactoryOptions;
|
||||
import org.hibernate.cache.spi.CacheDataDescription;
|
||||
import org.hibernate.cache.spi.TransactionalDataRegion;
|
||||
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;
|
||||
}
|
||||
|
||||
public boolean isTransactionAware() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public CacheDataDescription getCacheDataDescription() {
|
||||
return metadata;
|
||||
}
|
||||
|
||||
protected void throwIfAccessTypeUnsupported(AccessType accessType) {
|
||||
if ( supportedAccessTypes().contains( accessType ) ) {
|
||||
throw new UnsupportedOperationException( "This doesn't 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 SessionFactoryOptions getSessionFactoryOptions() {
|
||||
return options;
|
||||
}
|
||||
|
||||
public <T> T invoke(Object key, EntryProcessor<Object, Object, T> entryProcessor, Object... args) {
|
||||
return cache.invoke( key, entryProcessor, args);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,338 @@
|
|||
/*
|
||||
* 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 javax.cache.processor.EntryProcessor;
|
||||
import javax.cache.processor.EntryProcessorException;
|
||||
import javax.cache.processor.MutableEntry;
|
||||
|
||||
import org.hibernate.cache.CacheException;
|
||||
import org.hibernate.cache.jcache.JCacheTransactionalDataRegion;
|
||||
import org.hibernate.cache.spi.access.SoftLock;
|
||||
import org.hibernate.engine.spi.SharedSessionContractImplementor;
|
||||
|
||||
/**
|
||||
* @author Alex Snaps
|
||||
*/
|
||||
public class AbstractReadWriteRegionAccessStrategy<R extends JCacheTransactionalDataRegion> {
|
||||
protected final R region;
|
||||
protected final Comparator versionComparator;
|
||||
private final UUID uuid = UUID.randomUUID();
|
||||
private final AtomicLong nextLockId = 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 {
|
||||
return region.invoke(
|
||||
key, new EntryProcessor<Object, Object, Boolean>() {
|
||||
@Override
|
||||
public Boolean process(MutableEntry<Object, Object> entry, Object... args)
|
||||
throws EntryProcessorException {
|
||||
final Lockable item = (Lockable) entry.getValue();
|
||||
final boolean writeable = item == null || item.isWriteable(
|
||||
(Long) args[1],
|
||||
args[2],
|
||||
versionComparator
|
||||
);
|
||||
if ( writeable ) {
|
||||
entry.setValue( new Item( args[0], args[2], region.nextTimestamp() ) );
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}, value, txTimestamp, version);
|
||||
}
|
||||
|
||||
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 {
|
||||
return region.invoke(
|
||||
key, new EntryProcessor<Object, Object, SoftLock>() {
|
||||
@Override
|
||||
public SoftLock process(MutableEntry<Object, Object> entry, Object... args)
|
||||
throws EntryProcessorException {
|
||||
final Lockable item = (Lockable) entry.getValue();
|
||||
final long timeout = region.nextTimestamp() + region.getTimeout();
|
||||
final Lock lock = ( item == null ) ? new Lock(
|
||||
timeout,
|
||||
(UUID) args[0],
|
||||
(Long) args[1],
|
||||
args[2]
|
||||
)
|
||||
: item.lock( timeout, (UUID) args[0], (Long) args[1] );
|
||||
entry.setValue( lock );
|
||||
return lock;
|
||||
}
|
||||
}, uuid, nextLockId(), version
|
||||
);
|
||||
}
|
||||
|
||||
public void unlockItem(SharedSessionContractImplementor session, Object key, SoftLock lock) throws CacheException {
|
||||
region.invoke(
|
||||
key, new EntryProcessor<Object, Object, Void>() {
|
||||
@Override
|
||||
public Void process(MutableEntry<Object, Object> entry, Object... args)
|
||||
throws EntryProcessorException {
|
||||
final Lockable item = (Lockable) entry.getValue();
|
||||
|
||||
if ( (item != null) && item.isUnlockable( (SoftLock) args[0] ) ) {
|
||||
( (Lock) item ).unlock( region.nextTimestamp() );
|
||||
entry.setValue( item );
|
||||
}
|
||||
else {
|
||||
entry.setValue( null );
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}, lock);
|
||||
}
|
||||
|
||||
public void remove(SharedSessionContractImplementor session, Object key) throws CacheException {
|
||||
region.remove( key );
|
||||
}
|
||||
|
||||
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 {
|
||||
throw new UnsupportedOperationException( "JCache doesn't support region locking" );
|
||||
}
|
||||
|
||||
private long nextLockId() {
|
||||
return nextLockId.getAndIncrement();
|
||||
}
|
||||
|
||||
/**
|
||||
* 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;
|
||||
|
||||
/**
|
||||
* Creates an unlocked item wrapping the given value with a version and creation timestamp.
|
||||
*/
|
||||
Item(Object value, Object version, long timestamp) {
|
||||
this.value = value;
|
||||
this.version = version;
|
||||
this.timestamp = timestamp;
|
||||
}
|
||||
|
||||
@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 );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Wrapper type representing locked items.
|
||||
*/
|
||||
public static final class Lock implements Serializable, Lockable, SoftLock {
|
||||
private static final long serialVersionUID = 2L;
|
||||
|
||||
private final UUID sourceUuid;
|
||||
private final long lockId;
|
||||
private final Object version;
|
||||
|
||||
private long timeout;
|
||||
private boolean concurrent;
|
||||
private int multiplicity = 1;
|
||||
private 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 = timeout;
|
||||
this.lockId = lockId;
|
||||
this.version = version;
|
||||
this.sourceUuid = sourceUuid;
|
||||
}
|
||||
|
||||
@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) {
|
||||
return equals( lock );
|
||||
}
|
||||
|
||||
@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 );
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int hash = ( sourceUuid != null ? sourceUuid.hashCode() : 0 );
|
||||
int temp = (int) lockId;
|
||||
for ( int i = 1; i < Long.SIZE / Integer.SIZE; i++ ) {
|
||||
temp ^= ( lockId >>> ( i * Integer.SIZE ) );
|
||||
}
|
||||
return hash + temp;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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) {
|
||||
concurrent = true;
|
||||
multiplicity++;
|
||||
this.timeout = timeout;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Unlocks this Lock, and timestamps the unlock event.
|
||||
*/
|
||||
public void unlock(long timestamp) {
|
||||
if ( --multiplicity == 0 ) {
|
||||
unlockTimestamp = timestamp;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Lock Source-UUID:" + sourceUuid + " Lock-ID:" + lockId;
|
||||
}
|
||||
}
|
||||
}
|
97
hibernate-jcache/src/main/java/org/hibernate/cache/jcache/access/JCacheRegionAccessStrategy.java
vendored
Normal file
97
hibernate-jcache/src/main/java/org/hibernate/cache/jcache/access/JCacheRegionAccessStrategy.java
vendored
Normal file
|
@ -0,0 +1,97 @@
|
|||
/*
|
||||
* 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.cache.spi.access.RegionAccessStrategy;
|
||||
import org.hibernate.cache.spi.access.SoftLock;
|
||||
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 {
|
||||
// no op
|
||||
}
|
||||
|
||||
@Override
|
||||
public void remove(SharedSessionContractImplementor session, Object key) throws CacheException {
|
||||
region.remove( key );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeAll() throws CacheException {
|
||||
region.clear();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void evict(Object key) throws CacheException {
|
||||
region.remove( key );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void evictAll() throws CacheException {
|
||||
region.clear();
|
||||
}
|
||||
|
||||
public R getRegion() {
|
||||
return region;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,37 @@
|
|||
/*
|
||||
* 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.CollectionRegionAccessStrategy;
|
||||
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||
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.createCollectionKey( id, persister, factory, tenantIdentifier );
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getCacheKeyId(Object cacheKey) {
|
||||
return DefaultCacheKeysFactory.getCollectionId( cacheKey );
|
||||
}
|
||||
|
||||
}
|
|
@ -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.cache.jcache.access;
|
||||
|
||||
import org.hibernate.cache.CacheException;
|
||||
import org.hibernate.cache.internal.DefaultCacheKeysFactory;
|
||||
import org.hibernate.cache.jcache.JCacheEntityRegion;
|
||||
import org.hibernate.cache.spi.access.EntityRegionAccessStrategy;
|
||||
import org.hibernate.cache.spi.access.SoftLock;
|
||||
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.createEntityKey( id, persister, factory, tenantIdentifier );
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getCacheKeyId(Object cacheKey) {
|
||||
return DefaultCacheKeysFactory.getEntityId( cacheKey );
|
||||
}
|
||||
}
|
|
@ -0,0 +1,60 @@
|
|||
/*
|
||||
* 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.cache.spi.access.NaturalIdRegionAccessStrategy;
|
||||
import org.hibernate.cache.spi.access.SoftLock;
|
||||
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.createNaturalIdKey( naturalIdValues, persister, session );
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object[] getNaturalIdValues(Object cacheKey) {
|
||||
return DefaultCacheKeysFactory.getNaturalIdValues( cacheKey );
|
||||
}
|
||||
}
|
|
@ -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.jcache.access;
|
||||
|
||||
import org.hibernate.cache.internal.DefaultCacheKeysFactory;
|
||||
import org.hibernate.cache.jcache.JCacheCollectionRegion;
|
||||
import org.hibernate.cache.spi.access.CollectionRegionAccessStrategy;
|
||||
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.createCollectionKey( id, persister, factory, tenantIdentifier );
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getCacheKeyId(Object cacheKey) {
|
||||
return DefaultCacheKeysFactory.getCollectionId( cacheKey );
|
||||
}
|
||||
}
|
|
@ -0,0 +1,60 @@
|
|||
/*
|
||||
* 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.cache.spi.access.EntityRegionAccessStrategy;
|
||||
import org.hibernate.cache.spi.access.SoftLock;
|
||||
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.createEntityKey( id, persister, factory, tenantIdentifier );
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getCacheKeyId(Object cacheKey) {
|
||||
return DefaultCacheKeysFactory.getEntityId( cacheKey );
|
||||
}
|
||||
}
|
|
@ -0,0 +1,59 @@
|
|||
/*
|
||||
* 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.cache.spi.access.NaturalIdRegionAccessStrategy;
|
||||
import org.hibernate.cache.spi.access.SoftLock;
|
||||
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.createNaturalIdKey( naturalIdValues, persister, session );
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object[] getNaturalIdValues(Object cacheKey) {
|
||||
return DefaultCacheKeysFactory.getNaturalIdValues( cacheKey );
|
||||
}
|
||||
}
|
|
@ -0,0 +1,37 @@
|
|||
/*
|
||||
* 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.CollectionRegionAccessStrategy;
|
||||
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||
import org.hibernate.persister.collection.CollectionPersister;
|
||||
|
||||
/**
|
||||
* @author Alex Snaps
|
||||
*/
|
||||
public class ReadWriteCollectionRegionAccessStrategy
|
||||
extends AbstractReadWriteRegionAccessStrategy<JCacheCollectionRegion>
|
||||
implements CollectionRegionAccessStrategy {
|
||||
|
||||
public ReadWriteCollectionRegionAccessStrategy(JCacheCollectionRegion jCacheCollectionRegion) {
|
||||
super( jCacheCollectionRegion );
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object generateCacheKey(Object id, CollectionPersister persister, SessionFactoryImplementor factory, String tenantIdentifier) {
|
||||
return DefaultCacheKeysFactory.createCollectionKey( id, persister, factory, tenantIdentifier );
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getCacheKeyId(Object cacheKey) {
|
||||
return DefaultCacheKeysFactory.getCollectionId( cacheKey );
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,105 @@
|
|||
/*
|
||||
* 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 javax.cache.processor.EntryProcessor;
|
||||
import javax.cache.processor.EntryProcessorException;
|
||||
import javax.cache.processor.MutableEntry;
|
||||
|
||||
import org.hibernate.cache.CacheException;
|
||||
import org.hibernate.cache.internal.DefaultCacheKeysFactory;
|
||||
import org.hibernate.cache.jcache.JCacheEntityRegion;
|
||||
import org.hibernate.cache.spi.access.EntityRegionAccessStrategy;
|
||||
import org.hibernate.cache.spi.access.SoftLock;
|
||||
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.invoke(
|
||||
key, new EntryProcessor<Object, Object, Boolean>() {
|
||||
@Override
|
||||
public Boolean process(MutableEntry<Object, Object> entry, Object... args)
|
||||
throws EntryProcessorException {
|
||||
if ( !entry.exists() ) {
|
||||
entry.setValue( new Item( args[0], args[1], (Long) args[2] ) );
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}, value, version, region.nextTimestamp()
|
||||
);
|
||||
}
|
||||
|
||||
@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 {
|
||||
return region.invoke(
|
||||
key, new EntryProcessor<Object, Object, Boolean>() {
|
||||
@Override
|
||||
public Boolean process(MutableEntry<Object, Object> entry, Object... args)
|
||||
throws EntryProcessorException {
|
||||
final Lockable item = (Lockable) entry.getValue();
|
||||
|
||||
if ( item != null && item.isUnlockable( (SoftLock) args[3] ) ) {
|
||||
final Lock lockItem = (Lock) item;
|
||||
if ( lockItem.wasLockedConcurrently() ) {
|
||||
lockItem.unlock( (Long) args[1] );
|
||||
entry.setValue( lockItem );
|
||||
return false;
|
||||
}
|
||||
else {
|
||||
entry.setValue( new Item( args[0], args[1], (Long) args[4] ) );
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else {
|
||||
entry.setValue( null );
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
}, value, currentVersion, previousVersion, lock, region.nextTimestamp()
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object generateCacheKey(Object id, EntityPersister persister, SessionFactoryImplementor factory, String tenantIdentifier) {
|
||||
return DefaultCacheKeysFactory.createEntityKey( id, persister, factory, tenantIdentifier );
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getCacheKeyId(Object cacheKey) {
|
||||
return DefaultCacheKeysFactory.getEntityId( cacheKey );
|
||||
}
|
||||
}
|
|
@ -0,0 +1,104 @@
|
|||
/*
|
||||
* 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 javax.cache.processor.EntryProcessor;
|
||||
import javax.cache.processor.EntryProcessorException;
|
||||
import javax.cache.processor.MutableEntry;
|
||||
|
||||
import org.hibernate.cache.CacheException;
|
||||
import org.hibernate.cache.internal.DefaultCacheKeysFactory;
|
||||
import org.hibernate.cache.jcache.JCacheNaturalIdRegion;
|
||||
import org.hibernate.cache.spi.access.NaturalIdRegionAccessStrategy;
|
||||
import org.hibernate.cache.spi.access.SoftLock;
|
||||
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.invoke(
|
||||
key, new EntryProcessor<Object, Object, Boolean>() {
|
||||
@Override
|
||||
public Boolean process(MutableEntry<Object, Object> entry, Object... args)
|
||||
throws EntryProcessorException {
|
||||
if ( !entry.exists() ) {
|
||||
entry.setValue( new Item( args[0], null, (Long) args[1] ) );
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}, value, region.nextTimestamp()
|
||||
);
|
||||
}
|
||||
|
||||
@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 {
|
||||
return region.invoke(
|
||||
key, new EntryProcessor<Object, Object, Boolean>() {
|
||||
@Override
|
||||
public Boolean process(MutableEntry<Object, Object> entry, Object... args)
|
||||
throws EntryProcessorException {
|
||||
final Lockable item = (Lockable) entry.getValue();
|
||||
|
||||
if ( item != null && item.isUnlockable( (SoftLock) args[1] ) ) {
|
||||
final Lock lockItem = (Lock) item;
|
||||
if ( lockItem.wasLockedConcurrently() ) {
|
||||
lockItem.unlock( region.nextTimestamp() );
|
||||
entry.setValue( lockItem );
|
||||
return false;
|
||||
}
|
||||
else {
|
||||
entry.setValue( new Item( args[0], null, (Long) args[2] ) );
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else {
|
||||
entry.setValue( null );
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
}, value, lock, region.nextTimestamp()
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object generateCacheKey(Object[] naturalIdValues, EntityPersister persister, SharedSessionContractImplementor session) {
|
||||
return DefaultCacheKeysFactory.createNaturalIdKey( naturalIdValues, persister, session );
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object[] getNaturalIdValues(Object cacheKey) {
|
||||
return DefaultCacheKeysFactory.getNaturalIdValues( cacheKey );
|
||||
}
|
||||
}
|
11
hibernate-jcache/src/main/java/org/hibernate/cache/jcache/access/package-info.java
vendored
Normal file
11
hibernate-jcache/src/main/java/org/hibernate/cache/jcache/access/package-info.java
vendored
Normal file
|
@ -0,0 +1,11 @@
|
|||
/*
|
||||
* 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,11 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
|
||||
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Hibernate caching provider for JSR-107 compliant caches.
|
||||
*/
|
||||
package org.hibernate.cache.jcache;
|
34
hibernate-jcache/src/test/java/org/hibernate/cache/jcache/JCacheEntityRegionTest.java
vendored
Normal file
34
hibernate-jcache/src/test/java/org/hibernate/cache/jcache/JCacheEntityRegionTest.java
vendored
Normal file
|
@ -0,0 +1,34 @@
|
|||
package org.hibernate.cache.jcache;
|
||||
|
||||
import javax.cache.Cache;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.mockito.Mockito;
|
||||
|
||||
import org.hibernate.cache.spi.access.AccessType;
|
||||
import org.hibernate.cfg.Settings;
|
||||
|
||||
/**
|
||||
* @author Alex Snaps
|
||||
*/
|
||||
public class JCacheEntityRegionTest {
|
||||
|
||||
private JCacheEntityRegion region;
|
||||
|
||||
@Before
|
||||
public void createRegion() {
|
||||
final Cache<Object, Object> cache = Mockito.mock( Cache.class );
|
||||
region = new JCacheEntityRegion( cache, null, null );
|
||||
}
|
||||
|
||||
@Test(expected = UnsupportedOperationException.class)
|
||||
public void testThrowsWhenCreatingTxRegionAccess() {
|
||||
region.buildAccessStrategy( AccessType.TRANSACTIONAL );
|
||||
}
|
||||
|
||||
@Test(expected = UnsupportedOperationException.class)
|
||||
public void testThrowsWhenCreatingTxRegionAccessExplicitly() {
|
||||
region.createTransactionalEntityRegionAccessStrategy();
|
||||
}
|
||||
}
|
54
hibernate-jcache/src/test/java/org/hibernate/cache/jcache/JCacheGeneralDataRegionTest.java
vendored
Normal file
54
hibernate-jcache/src/test/java/org/hibernate/cache/jcache/JCacheGeneralDataRegionTest.java
vendored
Normal file
|
@ -0,0 +1,54 @@
|
|||
/*
|
||||
* 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.engine.spi.SessionImplementor;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.mockito.Mockito;
|
||||
|
||||
import static org.mockito.Mockito.verify;
|
||||
|
||||
/**
|
||||
* @author Alex Snaps
|
||||
*/
|
||||
public class JCacheGeneralDataRegionTest {
|
||||
|
||||
JCacheGeneralDataRegion region;
|
||||
|
||||
@Before
|
||||
public void createRegion() {
|
||||
final Cache<Object, Object> mock = Mockito.mock( Cache.class );
|
||||
region = new JCacheGeneralDataRegion( mock );
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDelegatesGetToCache() {
|
||||
region.get( Mockito.mock(SessionImplementor.class), "foo" );
|
||||
verify( region.getCache() ).get( "foo" );
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDelegatesPutToCache() {
|
||||
region.put( Mockito.mock(SessionImplementor.class), "foo", "bar" );
|
||||
verify( region.getCache() ).put( "foo", "bar" );
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDelegatesEvictKeyToCache() {
|
||||
region.evict( "foo" );
|
||||
verify( region.getCache() ).remove( "foo" );
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDelegatesEvictAllToCache() {
|
||||
region.evictAll();
|
||||
verify( region.getCache() ).removeAll();
|
||||
}
|
||||
}
|
132
hibernate-jcache/src/test/java/org/hibernate/cache/jcache/JCacheRegionFactoryTest.java
vendored
Normal file
132
hibernate-jcache/src/test/java/org/hibernate/cache/jcache/JCacheRegionFactoryTest.java
vendored
Normal file
|
@ -0,0 +1,132 @@
|
|||
/*
|
||||
* 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.Properties;
|
||||
|
||||
import javax.cache.Cache;
|
||||
import javax.cache.CacheManager;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import org.hibernate.cache.CacheException;
|
||||
import org.hibernate.cache.spi.access.AccessType;
|
||||
|
||||
import static java.util.Collections.EMPTY_MAP;
|
||||
import static org.hamcrest.CoreMatchers.is;
|
||||
import static org.hamcrest.CoreMatchers.notNullValue;
|
||||
import static org.hamcrest.CoreMatchers.nullValue;
|
||||
import static org.hamcrest.CoreMatchers.sameInstance;
|
||||
import static org.junit.Assert.assertThat;
|
||||
import static org.junit.Assert.fail;
|
||||
|
||||
/**
|
||||
* @author Alex Snaps
|
||||
*/
|
||||
public class JCacheRegionFactoryTest {
|
||||
|
||||
private JCacheRegionFactory factory;
|
||||
|
||||
@Before
|
||||
public void createFactory() {
|
||||
factory = new JCacheRegionFactory();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIsInitiallyNotStarted() {
|
||||
assertThat( factory.isStarted(), is( false ) );
|
||||
assertThat( factory.getCacheManager(), nullValue() );
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMaintainsStartedFlag() {
|
||||
factory.start( null, EMPTY_MAP );
|
||||
assertThat( factory.isStarted(), is( true ) );
|
||||
assertThat( factory.getCacheManager(), notNullValue() );
|
||||
factory.stop();
|
||||
assertThat( factory.isStarted(), is( false ) );
|
||||
assertThat( factory.getCacheManager(), nullValue() );
|
||||
}
|
||||
|
||||
@Test(expected = javax.cache.CacheException.class)
|
||||
public void testFailsOnNotFindingProvider() {
|
||||
final Properties properties = new Properties();
|
||||
properties.setProperty( JCacheRegionFactory.PROVIDER, "no.such.thing" );
|
||||
factory.start( null, properties );
|
||||
}
|
||||
|
||||
@Test(expected = CacheException.class)
|
||||
public void testFailsOnInvalidURI() {
|
||||
final Properties properties = new Properties();
|
||||
properties.setProperty( JCacheRegionFactory.CONFIG_URI, "_fil:" );
|
||||
factory.start( null, properties );
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDefaultAccessIsReadWrite() {
|
||||
assertThat( factory.getDefaultAccessType(), is( AccessType.READ_WRITE ) );
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUsesMinimalPutsAsDefault() {
|
||||
assertThat( factory.isMinimalPutsEnabledByDefault(), is( true ) );
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRemainsStoppedOnFailure() {
|
||||
final Properties properties = new Properties();
|
||||
properties.setProperty( JCacheRegionFactory.CONFIG_URI, "_fil:" );
|
||||
try {
|
||||
factory.start( null, properties );
|
||||
fail();
|
||||
}
|
||||
catch ( CacheException e ) {
|
||||
assertThat( factory.isStarted(), is( false ) );
|
||||
}
|
||||
|
||||
properties.setProperty( JCacheRegionFactory.PROVIDER, "no.such.thing" );
|
||||
try {
|
||||
factory.start( null, properties );
|
||||
fail();
|
||||
}
|
||||
catch ( javax.cache.CacheException e ) {
|
||||
assertThat( factory.isStarted(), is( false ) );
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testStopsCacheManagerOnShutdown() {
|
||||
factory.start( null, EMPTY_MAP );
|
||||
final CacheManager cacheManager = factory.getCacheManager();
|
||||
assertThat( cacheManager.isClosed(), is( false ) );
|
||||
factory.stop();
|
||||
assertThat(cacheManager.isClosed(), is(true));
|
||||
}
|
||||
|
||||
@Test(expected = IllegalStateException.class)
|
||||
public void testThrowsIllegalStateExceptionWhenNotStarted() {
|
||||
factory.getOrCreateCache( "foo", null, null );
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCreatesNonExistingCacheNamedLikeRegion() {
|
||||
factory.start( null, EMPTY_MAP );
|
||||
final Cache<Object, Object> foo = factory.getOrCreateCache( "foo", null, null );
|
||||
assertThat( foo, notNullValue());
|
||||
assertThat( factory.getCacheManager().getCache( "foo" ), sameInstance( foo ));
|
||||
assertThat( factory.getOrCreateCache( "foo", null, null ), sameInstance( foo ));
|
||||
}
|
||||
|
||||
@After
|
||||
public void stopFactory() {
|
||||
if ( factory.isStarted() ) {
|
||||
factory.stop();
|
||||
}
|
||||
}
|
||||
}
|
88
hibernate-jcache/src/test/java/org/hibernate/cache/jcache/JCacheRegionTest.java
vendored
Normal file
88
hibernate-jcache/src/test/java/org/hibernate/cache/jcache/JCacheRegionTest.java
vendored
Normal file
|
@ -0,0 +1,88 @@
|
|||
/*
|
||||
* 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.Iterator;
|
||||
import java.util.Map;
|
||||
import javax.cache.Cache;
|
||||
import javax.cache.CacheManager;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.mockito.Mockito;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.equalTo;
|
||||
import static org.hamcrest.CoreMatchers.is;
|
||||
import static org.junit.Assert.assertThat;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
/**
|
||||
* @author Alex Snaps
|
||||
*/
|
||||
public class JCacheRegionTest {
|
||||
|
||||
public static final String CACHE_NAME = "foo";
|
||||
private JCacheRegion region;
|
||||
|
||||
@Before
|
||||
public void createRegion() {
|
||||
final Cache mock = Mockito.mock( Cache.class );
|
||||
when( mock.getName() ).thenReturn( CACHE_NAME );
|
||||
this.region = new JCacheRegion( mock );
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDestroyCallsDestroyCacheOnCacheManager() {
|
||||
final Cache<Object, Object> cache = region.getCache();
|
||||
CacheManager cacheManager = Mockito.mock( CacheManager.class );
|
||||
when( cache.getCacheManager() ).thenReturn( cacheManager );
|
||||
when( cacheManager.getCache( CACHE_NAME ) ).thenReturn( cache );
|
||||
region.destroy();
|
||||
verify( cacheManager ).destroyCache( CACHE_NAME );
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDelegatesGetNameToCache() {
|
||||
assertThat( region.getName(), is( CACHE_NAME ) );
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDelegatesContainsToCache() {
|
||||
final Cache<Object, Object> cache = region.getCache();
|
||||
region.contains( "bar" );
|
||||
verify( cache ).containsKey( "bar" );
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSupportsToMap() {
|
||||
final Cache<Object, Object> cache = region.getCache();
|
||||
final Iterator mock = Mockito.mock( Iterator.class );
|
||||
when( mock.hasNext() ).thenReturn( true ).thenReturn( false );
|
||||
when( mock.next() ).thenReturn( new Cache.Entry<Object, Object>() {
|
||||
@Override
|
||||
public Object getKey() {
|
||||
return "foo";
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getValue() {
|
||||
return "bar";
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> T unwrap(Class<T> clazz) {
|
||||
throw new UnsupportedOperationException( "Implement me!" );
|
||||
}
|
||||
} );
|
||||
when( cache.iterator() ).thenReturn( mock );
|
||||
final Map<String, String> map = region.toMap();
|
||||
assertThat( map.size(), is(1) );
|
||||
assertThat( map.get( "foo" ), equalTo( "bar" ));
|
||||
}
|
||||
|
||||
}
|
71
hibernate-jcache/src/test/java/org/hibernate/cache/jcache/JCacheTransactionalDataRegionTest.java
vendored
Normal file
71
hibernate-jcache/src/test/java/org/hibernate/cache/jcache/JCacheTransactionalDataRegionTest.java
vendored
Normal file
|
@ -0,0 +1,71 @@
|
|||
package org.hibernate.cache.jcache;
|
||||
|
||||
import javax.cache.Cache;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.mockito.Mockito;
|
||||
|
||||
import org.hibernate.cache.spi.access.AccessType;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.is;
|
||||
import static org.junit.Assert.assertThat;
|
||||
import static org.mockito.Mockito.verify;
|
||||
|
||||
/**
|
||||
* @author Alex Snaps
|
||||
*/
|
||||
public class JCacheTransactionalDataRegionTest {
|
||||
|
||||
private JCacheTransactionalDataRegion region;
|
||||
|
||||
@Before
|
||||
public void createRegion() {
|
||||
final Cache<Object, Object> cache = Mockito.mock( Cache.class );
|
||||
region = new JCacheTransactionalDataRegion( cache, null, null );
|
||||
}
|
||||
|
||||
@Test(expected = NullPointerException.class)
|
||||
public void testThrowsOnNullCache() {
|
||||
new JCacheTransactionalDataRegion( null, null, null );
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIsNotTransactionAware() {
|
||||
assertThat( region.isTransactionAware(), is( false ) );
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDelegatesClearToCache() {
|
||||
final Cache<Object, Object> cache = region.getCache();
|
||||
region.clear();
|
||||
verify( cache ).removeAll();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDelegatesGetToCache() {
|
||||
final Cache<Object, Object> cache = region.getCache();
|
||||
region.get( "foo" );
|
||||
verify( cache ).get( "foo" );
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSupportsAllAccessTypesButTx() {
|
||||
for ( AccessType type : AccessType.values() ) {
|
||||
if ( type != AccessType.TRANSACTIONAL ) {
|
||||
assertThat(
|
||||
"JCacheTransactionalDataRegion should support " + type,
|
||||
region.supportedAccessTypes().contains( type ),
|
||||
is( true )
|
||||
);
|
||||
}
|
||||
else {
|
||||
assertThat(
|
||||
"JCacheTransactionalDataRegion NOT should support " + type,
|
||||
region.supportedAccessTypes().contains( type ),
|
||||
is( false )
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -110,6 +110,8 @@ ext {
|
|||
|
||||
c3p0: "com.mchange:c3p0:0.9.2.1",
|
||||
ehcache: "net.sf.ehcache:ehcache:2.10.1",
|
||||
ehcache3: "org.ehcache:ehcache:3.0.0",
|
||||
jcache: "javax.cache:cache-api:1.0.0",
|
||||
proxool: "proxool:proxool:0.8.3",
|
||||
hikaricp: "com.zaxxer:HikariCP-java6:2.3.9"
|
||||
|
||||
|
|
|
@ -19,6 +19,7 @@ include 'hibernate-c3p0'
|
|||
include 'hibernate-proxool'
|
||||
include 'hibernate-hikaricp'
|
||||
|
||||
include 'hibernate-jcache'
|
||||
include 'hibernate-ehcache'
|
||||
include 'hibernate-infinispan'
|
||||
|
||||
|
|
Loading…
Reference in New Issue