HHH-6297 remove legacy cache api
This commit is contained in:
parent
ad180ff95a
commit
92ad3eed80
|
@ -750,9 +750,9 @@ Customer customer = (Customer) session.get( Customer.class, customerId );
|
||||||
|
|
||||||
<tbody>
|
<tbody>
|
||||||
<row>
|
<row>
|
||||||
<entry>Hashtable (not intended for production use)</entry>
|
<entry>ConcurrentHashMap (only for testing purpose, in hibernate-testing module)</entry>
|
||||||
|
|
||||||
<entry><literal>org.hibernate.cache.internal.HashtableCacheProvider</literal></entry>
|
<entry><literal>org.hibernate.testing.cache.CachingRegionFactory</literal></entry>
|
||||||
|
|
||||||
<entry>memory</entry>
|
<entry>memory</entry>
|
||||||
|
|
||||||
|
@ -764,7 +764,7 @@ Customer customer = (Customer) session.get( Customer.class, customerId );
|
||||||
<row>
|
<row>
|
||||||
<entry>EHCache</entry>
|
<entry>EHCache</entry>
|
||||||
|
|
||||||
<entry><literal>org.hibernate.cache.internal.EhCacheProvider</literal></entry>
|
<entry><literal>org.hibernate.cache.internal.EhCacheRegionFactory</literal></entry>
|
||||||
|
|
||||||
<entry>memory, disk</entry>
|
<entry>memory, disk</entry>
|
||||||
|
|
||||||
|
@ -773,7 +773,7 @@ Customer customer = (Customer) session.get( Customer.class, customerId );
|
||||||
<entry>yes</entry>
|
<entry>yes</entry>
|
||||||
</row>
|
</row>
|
||||||
|
|
||||||
<row>
|
<!-- <row>
|
||||||
<entry>OSCache</entry>
|
<entry>OSCache</entry>
|
||||||
|
|
||||||
<entry><literal>org.hibernate.cache.OSCacheProvider</literal></entry>
|
<entry><literal>org.hibernate.cache.OSCacheProvider</literal></entry>
|
||||||
|
@ -818,6 +818,17 @@ Customer customer = (Customer) session.get( Customer.class, customerId );
|
||||||
|
|
||||||
<entry>yes (replication or invalidation)</entry>
|
<entry>yes (replication or invalidation)</entry>
|
||||||
|
|
||||||
|
<entry>yes (clock sync req.)</entry>
|
||||||
|
</row> -->
|
||||||
|
<row>
|
||||||
|
<entry>Infinispan</entry>
|
||||||
|
|
||||||
|
<entry><literal>org.hibernate.cache.infinispan.InfinispanRegionFactory</literal></entry>
|
||||||
|
|
||||||
|
<entry>clustered (ip multicast), transactional</entry>
|
||||||
|
|
||||||
|
<entry>yes (replication or invalidation)</entry>
|
||||||
|
|
||||||
<entry>yes (clock sync req.)</entry>
|
<entry>yes (clock sync req.)</entry>
|
||||||
</row>
|
</row>
|
||||||
</tbody>
|
</tbody>
|
||||||
|
@ -1114,7 +1125,7 @@ public SortedSet<Ticket> getTickets() {
|
||||||
|
|
||||||
<tbody>
|
<tbody>
|
||||||
<row>
|
<row>
|
||||||
<entry>Hashtable (not intended for production use)</entry>
|
<entry>ConcurrentHashMap (not intended for production use)</entry>
|
||||||
|
|
||||||
<entry>yes</entry>
|
<entry>yes</entry>
|
||||||
|
|
||||||
|
@ -1134,10 +1145,10 @@ public SortedSet<Ticket> getTickets() {
|
||||||
|
|
||||||
<entry>yes</entry>
|
<entry>yes</entry>
|
||||||
|
|
||||||
<entry></entry>
|
<entry>yes</entry>
|
||||||
</row>
|
</row>
|
||||||
|
|
||||||
<row>
|
<!-- <row>
|
||||||
<entry>OSCache</entry>
|
<entry>OSCache</entry>
|
||||||
|
|
||||||
<entry>yes</entry>
|
<entry>yes</entry>
|
||||||
|
@ -1182,6 +1193,17 @@ public SortedSet<Ticket> getTickets() {
|
||||||
|
|
||||||
<entry></entry>
|
<entry></entry>
|
||||||
|
|
||||||
|
<entry>yes</entry>
|
||||||
|
</row> -->
|
||||||
|
<row>
|
||||||
|
<entry>Infinispan</entry>
|
||||||
|
|
||||||
|
<entry>yes</entry>
|
||||||
|
|
||||||
|
<entry></entry>
|
||||||
|
|
||||||
|
<entry></entry>
|
||||||
|
|
||||||
<entry>yes</entry>
|
<entry>yes</entry>
|
||||||
</row>
|
</row>
|
||||||
</tbody>
|
</tbody>
|
||||||
|
|
|
@ -492,13 +492,11 @@ hibernate.cache.region_prefix hibernate.test
|
||||||
|
|
||||||
## choose a cache implementation
|
## choose a cache implementation
|
||||||
|
|
||||||
#hibernate.cache.provider_class org.hibernate.cache.EhCacheProvider
|
#hibernate.cache.region.factory_class org.hibernate.cache.infinispan.InfinispanRegionFactory
|
||||||
#hibernate.cache.provider_class org.hibernate.cache.EmptyCacheProvider
|
#hibernate.cache.region.factory_class org.hibernate.cache.infinispan.JndiInfinispanRegionFactory
|
||||||
hibernate.cache.provider_class org.hibernate.cache.internal.HashtableCacheProvider
|
#hibernate.cache.region.factory_class org.hibernate.cache.internal.EhCacheRegionFactory
|
||||||
#hibernate.cache.provider_class org.hibernate.cache.TreeCacheProvider
|
#hibernate.cache.region.factory_class org.hibernate.cache.internal.SingletonEhCacheRegionFactory
|
||||||
#hibernate.cache.provider_class org.hibernate.cache.OSCacheProvider
|
hibernate.cache.region.factory_class org.hibernate.cache.internal.NoCachingRegionFactory
|
||||||
#hibernate.cache.provider_class org.hibernate.cache.SwarmCacheProvider
|
|
||||||
|
|
||||||
|
|
||||||
## choose a custom query cache implementation
|
## choose a custom query cache implementation
|
||||||
|
|
||||||
|
|
|
@ -451,12 +451,11 @@ hibernate.cache.region_prefix hibernate.test
|
||||||
|
|
||||||
## choose a cache implementation
|
## choose a cache implementation
|
||||||
|
|
||||||
#hibernate.cache.provider_class org.hibernate.cache.EhCacheProvider
|
#hibernate.cache.region.factory_class org.hibernate.cache.infinispan.InfinispanRegionFactory
|
||||||
#hibernate.cache.provider_class org.hibernate.cache.EmptyCacheProvider
|
#hibernate.cache.region.factory_class org.hibernate.cache.infinispan.JndiInfinispanRegionFactory
|
||||||
hibernate.cache.provider_class org.hibernate.cache.HashtableCacheProvider
|
#hibernate.cache.region.factory_class org.hibernate.cache.internal.EhCacheRegionFactory
|
||||||
#hibernate.cache.provider_class org.hibernate.cache.TreeCacheProvider
|
#hibernate.cache.region.factory_class org.hibernate.cache.internal.SingletonEhCacheRegionFactory
|
||||||
#hibernate.cache.provider_class org.hibernate.cache.OSCacheProvider
|
#hibernate.cache.region.factory_class org.hibernate.cache.internal.NoCachingRegionFactory
|
||||||
#hibernate.cache.provider_class org.hibernate.cache.SwarmCacheProvider
|
|
||||||
|
|
||||||
|
|
||||||
## choose a custom query cache implementation
|
## choose a custom query cache implementation
|
||||||
|
|
|
@ -25,7 +25,10 @@ package org.hibernate;
|
||||||
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
|
import org.jboss.logging.Logger;
|
||||||
|
|
||||||
import org.hibernate.cfg.Environment;
|
import org.hibernate.cfg.Environment;
|
||||||
|
import org.hibernate.internal.CoreMessageLogger;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Describes the methods for multi-tenancy understood by Hibernate.
|
* Describes the methods for multi-tenancy understood by Hibernate.
|
||||||
|
@ -33,6 +36,7 @@ import org.hibernate.cfg.Environment;
|
||||||
* @author Steve Ebersole
|
* @author Steve Ebersole
|
||||||
*/
|
*/
|
||||||
public enum MultiTenancyStrategy {
|
public enum MultiTenancyStrategy {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Multi-tenancy implemented by use of discriminator columns.
|
* Multi-tenancy implemented by use of discriminator columns.
|
||||||
*/
|
*/
|
||||||
|
@ -49,7 +53,10 @@ public enum MultiTenancyStrategy {
|
||||||
* No multi-tenancy
|
* No multi-tenancy
|
||||||
*/
|
*/
|
||||||
NONE;
|
NONE;
|
||||||
|
private static final CoreMessageLogger LOG = Logger.getMessageLogger(
|
||||||
|
CoreMessageLogger.class,
|
||||||
|
MultiTenancyStrategy.class.getName()
|
||||||
|
);
|
||||||
public static MultiTenancyStrategy determineMultiTenancyStrategy(Map properties) {
|
public static MultiTenancyStrategy determineMultiTenancyStrategy(Map properties) {
|
||||||
final Object strategy = properties.get( Environment.MULTI_TENANT );
|
final Object strategy = properties.get( Environment.MULTI_TENANT );
|
||||||
if ( strategy == null ) {
|
if ( strategy == null ) {
|
||||||
|
@ -61,20 +68,11 @@ public enum MultiTenancyStrategy {
|
||||||
}
|
}
|
||||||
|
|
||||||
final String strategyName = strategy.toString();
|
final String strategyName = strategy.toString();
|
||||||
if ( MultiTenancyStrategy.DISCRIMINATOR.name().equals( strategyName ) ) {
|
try {
|
||||||
return MultiTenancyStrategy.DISCRIMINATOR;
|
return MultiTenancyStrategy.valueOf( strategyName.toUpperCase() );
|
||||||
}
|
}
|
||||||
else if ( MultiTenancyStrategy.SCHEMA.name().equals( strategyName ) ) {
|
catch ( RuntimeException e ) {
|
||||||
return MultiTenancyStrategy.SCHEMA;
|
LOG.warn( "Unknown multi tenancy strategy [ " +strategyName +" ], using MultiTenancyStrategy.NONE." );
|
||||||
}
|
|
||||||
else if ( MultiTenancyStrategy.DATABASE.name().equals( strategyName ) ) {
|
|
||||||
return MultiTenancyStrategy.DATABASE;
|
|
||||||
}
|
|
||||||
else if ( MultiTenancyStrategy.NONE.name().equals( strategyName ) ) {
|
|
||||||
return MultiTenancyStrategy.NONE;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
// todo log?
|
|
||||||
return MultiTenancyStrategy.NONE;
|
return MultiTenancyStrategy.NONE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,114 +0,0 @@
|
||||||
/*
|
|
||||||
* Hibernate, Relational Persistence for Idiomatic Java
|
|
||||||
*
|
|
||||||
* Copyright (c) 2008-2011, Red Hat Inc. or third-party contributors as
|
|
||||||
* indicated by the @author tags or express copyright attribution
|
|
||||||
* statements applied by the authors. All third-party contributions are
|
|
||||||
* distributed under license by Red Hat Inc.
|
|
||||||
*
|
|
||||||
* This copyrighted material is made available to anyone wishing to use, modify,
|
|
||||||
* copy, or redistribute it subject to the terms and conditions of the GNU
|
|
||||||
* Lesser General Public License, as published by the Free Software Foundation.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
|
||||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
|
||||||
* for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Lesser General Public License
|
|
||||||
* along with this distribution; if not, write to:
|
|
||||||
* Free Software Foundation, Inc.
|
|
||||||
* 51 Franklin Street, Fifth Floor
|
|
||||||
* Boston, MA 02110-1301 USA
|
|
||||||
*/
|
|
||||||
package org.hibernate.cache.internal;
|
|
||||||
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.Hashtable;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
import org.hibernate.cache.CacheException;
|
|
||||||
import org.hibernate.cache.spi.Cache;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A lightweight implementation of the <tt>Cache</tt> interface
|
|
||||||
* @author Gavin King
|
|
||||||
*/
|
|
||||||
public class HashtableCache implements Cache {
|
|
||||||
|
|
||||||
private final Map hashtable = new Hashtable();
|
|
||||||
private final String regionName;
|
|
||||||
|
|
||||||
public HashtableCache(String regionName) {
|
|
||||||
this.regionName = regionName;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getRegionName() {
|
|
||||||
return regionName;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Object read(Object key) throws CacheException {
|
|
||||||
return hashtable.get(key);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Object get(Object key) throws CacheException {
|
|
||||||
return hashtable.get(key);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void update(Object key, Object value) throws CacheException {
|
|
||||||
put(key, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void put(Object key, Object value) throws CacheException {
|
|
||||||
hashtable.put(key, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void remove(Object key) throws CacheException {
|
|
||||||
hashtable.remove(key);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void clear() throws CacheException {
|
|
||||||
hashtable.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void destroy() throws CacheException {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public void lock(Object key) throws CacheException {
|
|
||||||
// local cache, so we use synchronization
|
|
||||||
}
|
|
||||||
|
|
||||||
public void unlock(Object key) throws CacheException {
|
|
||||||
// local cache, so we use synchronization
|
|
||||||
}
|
|
||||||
|
|
||||||
public long nextTimestamp() {
|
|
||||||
return Timestamper.next();
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getTimeout() {
|
|
||||||
return Timestamper.ONE_MS * 60000; //ie. 60 seconds
|
|
||||||
}
|
|
||||||
|
|
||||||
public long getSizeInMemory() {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
public long getElementCountInMemory() {
|
|
||||||
return hashtable.size();
|
|
||||||
}
|
|
||||||
|
|
||||||
public long getElementCountOnDisk() {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Map toMap() {
|
|
||||||
return Collections.unmodifiableMap(hashtable);
|
|
||||||
}
|
|
||||||
|
|
||||||
public String toString() {
|
|
||||||
return "HashtableCache(" + regionName + ')';
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,86 +0,0 @@
|
||||||
/*
|
|
||||||
* Hibernate, Relational Persistence for Idiomatic Java
|
|
||||||
*
|
|
||||||
* Copyright (c) 2008-2011, Red Hat Inc. or third-party contributors as
|
|
||||||
* indicated by the @author tags or express copyright attribution
|
|
||||||
* statements applied by the authors. All third-party contributions are
|
|
||||||
* distributed under license by Red Hat Inc.
|
|
||||||
*
|
|
||||||
* This copyrighted material is made available to anyone wishing to use, modify,
|
|
||||||
* copy, or redistribute it subject to the terms and conditions of the GNU
|
|
||||||
* Lesser General Public License, as published by the Free Software Foundation.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
|
||||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
|
||||||
* for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Lesser General Public License
|
|
||||||
* along with this distribution; if not, write to:
|
|
||||||
* Free Software Foundation, Inc.
|
|
||||||
* 51 Franklin Street, Fifth Floor
|
|
||||||
* Boston, MA 02110-1301 USA
|
|
||||||
*/
|
|
||||||
package org.hibernate.cache.internal;
|
|
||||||
|
|
||||||
import java.util.Properties;
|
|
||||||
|
|
||||||
import org.hibernate.cache.CacheException;
|
|
||||||
import org.hibernate.cache.NoCachingEnabledException;
|
|
||||||
import org.hibernate.cache.spi.Cache;
|
|
||||||
import org.hibernate.cache.spi.CacheProvider;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Implementation of NoCacheProvider.
|
|
||||||
*
|
|
||||||
* @author Steve Ebersole
|
|
||||||
*/
|
|
||||||
@Deprecated
|
|
||||||
public class NoCacheProvider implements CacheProvider {
|
|
||||||
/**
|
|
||||||
* Configure the cache
|
|
||||||
*
|
|
||||||
* @param regionName the name of the cache region
|
|
||||||
* @param properties configuration settings
|
|
||||||
*
|
|
||||||
* @throws org.hibernate.cache.CacheException
|
|
||||||
*/
|
|
||||||
public Cache buildCache(String regionName, Properties properties) throws CacheException {
|
|
||||||
throw new NoCachingEnabledException();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Generate a timestamp
|
|
||||||
*/
|
|
||||||
public long nextTimestamp() {
|
|
||||||
// This, is used by SessionFactoryImpl to hand to the generated SessionImpl;
|
|
||||||
// was the only reason I could see that we cannot just use null as
|
|
||||||
// Settings.cacheProvider
|
|
||||||
return System.currentTimeMillis() / 100;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Callback to perform any necessary initialization of the underlying cache implementation during SessionFactory
|
|
||||||
* construction.
|
|
||||||
*
|
|
||||||
* @param properties current configuration settings.
|
|
||||||
*/
|
|
||||||
public void start(Properties properties) throws CacheException {
|
|
||||||
// this is called by SessionFactory irregardless; we just disregard here;
|
|
||||||
// could also add a check to SessionFactory to only conditionally call start
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Callback to perform any necessary cleanup of the underlying cache implementation during SessionFactory.close().
|
|
||||||
*/
|
|
||||||
public void stop() {
|
|
||||||
// this is called by SessionFactory irregardless; we just disregard here;
|
|
||||||
// could also add a check to SessionFactory to only conditionally call stop
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isMinimalPutsEnabledByDefault() {
|
|
||||||
// this is called from SettingsFactory irregardless; trivial to simply disregard
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -23,28 +23,27 @@
|
||||||
*/
|
*/
|
||||||
package org.hibernate.cache.internal;
|
package org.hibernate.cache.internal;
|
||||||
|
|
||||||
|
import java.util.concurrent.atomic.AtomicLong;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generates increasing identifiers (in a single VM only). Not valid across multiple VMs. Identifiers are not
|
* Generates increasing identifiers (in a single VM only). Not valid across multiple VMs. Identifiers are not
|
||||||
* necessarily strictly increasing, but usually are.
|
* necessarily strictly increasing, but usually are.
|
||||||
*/
|
*/
|
||||||
public final class Timestamper {
|
public final class Timestamper {
|
||||||
private static short counter = 0;
|
|
||||||
private static long time;
|
|
||||||
private static final int BIN_DIGITS = 12;
|
private static final int BIN_DIGITS = 12;
|
||||||
public static final short ONE_MS = 1<<BIN_DIGITS;
|
public static final short ONE_MS = 1<<BIN_DIGITS;
|
||||||
|
private static final AtomicLong VALUE = new AtomicLong();
|
||||||
public static long next() {
|
public static long next() {
|
||||||
synchronized(Timestamper.class) {
|
while (true) {
|
||||||
long newTime = System.currentTimeMillis() << BIN_DIGITS;
|
long base = System.currentTimeMillis() << BIN_DIGITS;
|
||||||
if (time<newTime) {
|
long maxValue = base + ONE_MS - 1;
|
||||||
time = newTime;
|
|
||||||
counter = 0;
|
|
||||||
}
|
|
||||||
else if (counter < ONE_MS - 1 ) {
|
|
||||||
counter++;
|
|
||||||
}
|
|
||||||
|
|
||||||
return time + counter;
|
for (long current = VALUE.get(), update = Math.max(base, current + 1); update < maxValue;
|
||||||
|
current = VALUE.get(), update = Math.max(base, current + 1)) {
|
||||||
|
if (VALUE.compareAndSet(current, update)) {
|
||||||
|
return update;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,114 +0,0 @@
|
||||||
/*
|
|
||||||
* Hibernate, Relational Persistence for Idiomatic Java
|
|
||||||
*
|
|
||||||
* Copyright (c) 2008-2011, Red Hat Inc. or third-party contributors as
|
|
||||||
* indicated by the @author tags or express copyright attribution
|
|
||||||
* statements applied by the authors. All third-party contributions are
|
|
||||||
* distributed under license by Red Hat Inc.
|
|
||||||
*
|
|
||||||
* This copyrighted material is made available to anyone wishing to use, modify,
|
|
||||||
* copy, or redistribute it subject to the terms and conditions of the GNU
|
|
||||||
* Lesser General Public License, as published by the Free Software Foundation.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
|
||||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
|
||||||
* for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Lesser General Public License
|
|
||||||
* along with this distribution; if not, write to:
|
|
||||||
* Free Software Foundation, Inc.
|
|
||||||
* 51 Franklin Street, Fifth Floor
|
|
||||||
* Boston, MA 02110-1301 USA
|
|
||||||
*/
|
|
||||||
package org.hibernate.cache.internal.bridge;
|
|
||||||
|
|
||||||
import org.hibernate.cache.CacheException;
|
|
||||||
import org.hibernate.cache.spi.CacheConcurrencyStrategy;
|
|
||||||
import org.hibernate.cache.spi.CollectionRegion;
|
|
||||||
import org.hibernate.cache.spi.access.CollectionRegionAccessStrategy;
|
|
||||||
import org.hibernate.cache.spi.access.SoftLock;
|
|
||||||
import org.hibernate.cfg.Settings;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Adapter specifically bridging {@link CollectionRegionAccessStrategy} to {@link CacheConcurrencyStrategy}.
|
|
||||||
*
|
|
||||||
* @author Steve Ebersole
|
|
||||||
*/
|
|
||||||
public class CollectionAccessStrategyAdapter implements CollectionRegionAccessStrategy {
|
|
||||||
private final CollectionRegion region;
|
|
||||||
private final CacheConcurrencyStrategy ccs;
|
|
||||||
private final Settings settings;
|
|
||||||
|
|
||||||
public CollectionAccessStrategyAdapter(CollectionRegion region, CacheConcurrencyStrategy ccs, Settings settings) {
|
|
||||||
this.region = region;
|
|
||||||
this.ccs = ccs;
|
|
||||||
this.settings = settings;
|
|
||||||
}
|
|
||||||
|
|
||||||
public CollectionRegion getRegion() {
|
|
||||||
return region;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Object get(Object key, long txTimestamp) throws CacheException {
|
|
||||||
return ccs.get( key, txTimestamp );
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean putFromLoad(Object key, Object value, long txTimestamp, Object version) throws CacheException {
|
|
||||||
return putFromLoad( key, value, txTimestamp, version, settings.isMinimalPutsEnabled() );
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean putFromLoad(
|
|
||||||
Object key,
|
|
||||||
Object value,
|
|
||||||
long txTimestamp,
|
|
||||||
Object version,
|
|
||||||
boolean minimalPutOverride) throws CacheException {
|
|
||||||
return ccs.put( key, value, txTimestamp, version, region.getCacheDataDescription().getVersionComparator(), minimalPutOverride );
|
|
||||||
}
|
|
||||||
|
|
||||||
public SoftLock lockItem(Object key, Object version) throws CacheException {
|
|
||||||
return ccs.lock( key, version );
|
|
||||||
}
|
|
||||||
|
|
||||||
public SoftLock lockRegion() throws CacheException {
|
|
||||||
// no-op; CCS did not have such a concept
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void unlockItem(Object key, SoftLock lock) throws CacheException {
|
|
||||||
ccs.release( key, lock );
|
|
||||||
}
|
|
||||||
|
|
||||||
public void unlockRegion(SoftLock lock) throws CacheException {
|
|
||||||
// again, CCS did not have such a concept; but a reasonable
|
|
||||||
// proximity is to clear the cache after transaction *as long as*
|
|
||||||
// the underlying cache is not JTA aware.
|
|
||||||
if ( !region.isTransactionAware() ) {
|
|
||||||
ccs.clear();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void remove(Object key) throws CacheException {
|
|
||||||
ccs.evict( key );
|
|
||||||
}
|
|
||||||
|
|
||||||
public void removeAll() throws CacheException {
|
|
||||||
// again, CCS did not have such a concept; however a reasonable
|
|
||||||
// proximity is to clear the cache. For non-transaction aware
|
|
||||||
// caches, we will also do a clear at the end of the transaction
|
|
||||||
ccs.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void evict(Object key) throws CacheException {
|
|
||||||
ccs.remove( key );
|
|
||||||
}
|
|
||||||
|
|
||||||
public void evictAll() throws CacheException {
|
|
||||||
ccs.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void destroy() {
|
|
||||||
ccs.destroy();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,81 +0,0 @@
|
||||||
/*
|
|
||||||
* Hibernate, Relational Persistence for Idiomatic Java
|
|
||||||
*
|
|
||||||
* Copyright (c) 2008-2011, Red Hat Inc. or third-party contributors as
|
|
||||||
* indicated by the @author tags or express copyright attribution
|
|
||||||
* statements applied by the authors. All third-party contributions are
|
|
||||||
* distributed under license by Red Hat Inc.
|
|
||||||
*
|
|
||||||
* This copyrighted material is made available to anyone wishing to use, modify,
|
|
||||||
* copy, or redistribute it subject to the terms and conditions of the GNU
|
|
||||||
* Lesser General Public License, as published by the Free Software Foundation.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
|
||||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
|
||||||
* for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Lesser General Public License
|
|
||||||
* along with this distribution; if not, write to:
|
|
||||||
* Free Software Foundation, Inc.
|
|
||||||
* 51 Franklin Street, Fifth Floor
|
|
||||||
* Boston, MA 02110-1301 USA
|
|
||||||
*/
|
|
||||||
package org.hibernate.cache.internal.bridge;
|
|
||||||
|
|
||||||
import org.jboss.logging.Logger;
|
|
||||||
|
|
||||||
import org.hibernate.cache.CacheException;
|
|
||||||
import org.hibernate.cache.spi.Cache;
|
|
||||||
import org.hibernate.cache.spi.CacheConcurrencyStrategy;
|
|
||||||
import org.hibernate.cache.spi.CacheDataDescription;
|
|
||||||
import org.hibernate.cache.spi.CollectionRegion;
|
|
||||||
import org.hibernate.cache.spi.NonstrictReadWriteCache;
|
|
||||||
import org.hibernate.cache.spi.OptimisticCache;
|
|
||||||
import org.hibernate.cache.spi.ReadOnlyCache;
|
|
||||||
import org.hibernate.cache.spi.ReadWriteCache;
|
|
||||||
import org.hibernate.cache.spi.TransactionalCache;
|
|
||||||
import org.hibernate.cache.spi.access.AccessType;
|
|
||||||
import org.hibernate.cache.spi.access.CollectionRegionAccessStrategy;
|
|
||||||
import org.hibernate.cfg.Settings;
|
|
||||||
import org.hibernate.internal.CoreMessageLogger;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Adapter specifically bridging {@link CollectionRegion} to {@link Cache}.
|
|
||||||
*
|
|
||||||
* @author Steve Ebersole
|
|
||||||
*/
|
|
||||||
public class CollectionRegionAdapter extends BaseTransactionalDataRegionAdapter implements CollectionRegion {
|
|
||||||
|
|
||||||
private static final CoreMessageLogger LOG = Logger.getMessageLogger(CoreMessageLogger.class,
|
|
||||||
CollectionRegionAdapter.class.getName());
|
|
||||||
|
|
||||||
public CollectionRegionAdapter(Cache underlyingCache, Settings settings, CacheDataDescription metadata) {
|
|
||||||
super( underlyingCache, settings, metadata );
|
|
||||||
if ( underlyingCache instanceof OptimisticCache ) {
|
|
||||||
( ( OptimisticCache ) underlyingCache ).setSource( new OptimisticCacheSourceAdapter( metadata ) );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public CollectionRegionAccessStrategy buildAccessStrategy(AccessType accessType) throws CacheException {
|
|
||||||
CacheConcurrencyStrategy ccs;
|
|
||||||
if ( AccessType.READ_ONLY.equals( accessType ) ) {
|
|
||||||
if (metadata.isMutable()) LOG.readOnlyCacheConfiguredForMutableCollection(getName());
|
|
||||||
ccs = new ReadOnlyCache();
|
|
||||||
}
|
|
||||||
else if ( AccessType.READ_WRITE.equals( accessType ) ) {
|
|
||||||
ccs = new ReadWriteCache();
|
|
||||||
}
|
|
||||||
else if ( AccessType.NONSTRICT_READ_WRITE.equals( accessType ) ) {
|
|
||||||
ccs = new NonstrictReadWriteCache();
|
|
||||||
}
|
|
||||||
else if ( AccessType.TRANSACTIONAL.equals( accessType ) ) {
|
|
||||||
ccs = new TransactionalCache();
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
throw new IllegalArgumentException( "unrecognized access strategy type [" + accessType + "]" );
|
|
||||||
}
|
|
||||||
ccs.setCache( underlyingCache );
|
|
||||||
return new CollectionAccessStrategyAdapter( this, ccs, settings );
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,132 +0,0 @@
|
||||||
/*
|
|
||||||
* Hibernate, Relational Persistence for Idiomatic Java
|
|
||||||
*
|
|
||||||
* Copyright (c) 2008-2011, Red Hat Inc. or third-party contributors as
|
|
||||||
* indicated by the @author tags or express copyright attribution
|
|
||||||
* statements applied by the authors. All third-party contributions are
|
|
||||||
* distributed under license by Red Hat Inc.
|
|
||||||
*
|
|
||||||
* This copyrighted material is made available to anyone wishing to use, modify,
|
|
||||||
* copy, or redistribute it subject to the terms and conditions of the GNU
|
|
||||||
* Lesser General Public License, as published by the Free Software Foundation.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
|
||||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
|
||||||
* for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Lesser General Public License
|
|
||||||
* along with this distribution; if not, write to:
|
|
||||||
* Free Software Foundation, Inc.
|
|
||||||
* 51 Franklin Street, Fifth Floor
|
|
||||||
* Boston, MA 02110-1301 USA
|
|
||||||
*/
|
|
||||||
package org.hibernate.cache.internal.bridge;
|
|
||||||
|
|
||||||
import org.hibernate.cache.CacheException;
|
|
||||||
import org.hibernate.cache.spi.CacheConcurrencyStrategy;
|
|
||||||
import org.hibernate.cache.spi.EntityRegion;
|
|
||||||
import org.hibernate.cache.spi.access.EntityRegionAccessStrategy;
|
|
||||||
import org.hibernate.cache.spi.access.SoftLock;
|
|
||||||
import org.hibernate.cfg.Settings;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Adapter specifically bridging {@link EntityRegionAccessStrategy} to {@link CacheConcurrencyStrategy}.
|
|
||||||
*
|
|
||||||
* @author Steve Ebersole
|
|
||||||
*/
|
|
||||||
public class EntityAccessStrategyAdapter implements EntityRegionAccessStrategy {
|
|
||||||
private final EntityRegion region;
|
|
||||||
private final CacheConcurrencyStrategy ccs;
|
|
||||||
private final Settings settings;
|
|
||||||
|
|
||||||
public EntityAccessStrategyAdapter(EntityRegion region, CacheConcurrencyStrategy ccs, Settings settings) {
|
|
||||||
this.region = region;
|
|
||||||
this.ccs = ccs;
|
|
||||||
this.settings = settings;
|
|
||||||
}
|
|
||||||
|
|
||||||
public EntityRegion getRegion() {
|
|
||||||
return region;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Object get(Object key, long txTimestamp) throws CacheException {
|
|
||||||
return ccs.get( key, txTimestamp );
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean putFromLoad(Object key, Object value, long txTimestamp, Object version) throws CacheException {
|
|
||||||
return putFromLoad( key, value, txTimestamp, version, settings.isMinimalPutsEnabled() );
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean putFromLoad(
|
|
||||||
Object key,
|
|
||||||
Object value,
|
|
||||||
long txTimestamp,
|
|
||||||
Object version,
|
|
||||||
boolean minimalPutOverride) throws CacheException {
|
|
||||||
return ccs.put( key, value, txTimestamp, version, region.getCacheDataDescription().getVersionComparator(), minimalPutOverride );
|
|
||||||
}
|
|
||||||
|
|
||||||
public SoftLock lockItem(Object key, Object version) throws CacheException {
|
|
||||||
return ccs.lock( key, version );
|
|
||||||
}
|
|
||||||
|
|
||||||
public SoftLock lockRegion() throws CacheException {
|
|
||||||
// no-op; CCS did not have such a concept
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void unlockItem(Object key, SoftLock lock) throws CacheException {
|
|
||||||
ccs.release( key, lock );
|
|
||||||
}
|
|
||||||
|
|
||||||
public void unlockRegion(SoftLock lock) throws CacheException {
|
|
||||||
// again, CCS did not have such a concept; but a reasonable
|
|
||||||
// proximity is to clear the cache after transaction *as long as*
|
|
||||||
// the underlying cache is not JTA aware.
|
|
||||||
if ( !region.isTransactionAware() ) {
|
|
||||||
ccs.clear();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean insert(Object key, Object value, Object version) throws CacheException {
|
|
||||||
return ccs.insert( key, value, version );
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean afterInsert(Object key, Object value, Object version) throws CacheException {
|
|
||||||
return ccs.afterInsert( key, value, version );
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean update(Object key, Object value, Object currentVersion, Object previousVersion)
|
|
||||||
throws CacheException {
|
|
||||||
return ccs.update( key, value, currentVersion, previousVersion );
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean afterUpdate(Object key, Object value, Object currentVersion, Object previousVersion, SoftLock lock)
|
|
||||||
throws CacheException {
|
|
||||||
return ccs.afterUpdate( key, value, currentVersion, lock );
|
|
||||||
}
|
|
||||||
|
|
||||||
public void remove(Object key) throws CacheException {
|
|
||||||
ccs.evict( key );
|
|
||||||
}
|
|
||||||
|
|
||||||
public void removeAll() throws CacheException {
|
|
||||||
// again, CCS did not have such a concept; however a reasonable
|
|
||||||
// proximity is to clear the cache. For non-transaction aware
|
|
||||||
// caches, we will also do a clear at the end of the transaction
|
|
||||||
ccs.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void evict(Object key) throws CacheException {
|
|
||||||
ccs.remove( key );
|
|
||||||
}
|
|
||||||
|
|
||||||
public void evictAll() throws CacheException {
|
|
||||||
ccs.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void destroy() {
|
|
||||||
ccs.destroy();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,80 +0,0 @@
|
||||||
/*
|
|
||||||
* Hibernate, Relational Persistence for Idiomatic Java
|
|
||||||
*
|
|
||||||
* Copyright (c) 2008-2011, Red Hat Inc. or third-party contributors as
|
|
||||||
* indicated by the @author tags or express copyright attribution
|
|
||||||
* statements applied by the authors. All third-party contributions are
|
|
||||||
* distributed under license by Red Hat Inc.
|
|
||||||
*
|
|
||||||
* This copyrighted material is made available to anyone wishing to use, modify,
|
|
||||||
* copy, or redistribute it subject to the terms and conditions of the GNU
|
|
||||||
* Lesser General Public License, as published by the Free Software Foundation.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
|
||||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
|
||||||
* for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Lesser General Public License
|
|
||||||
* along with this distribution; if not, write to:
|
|
||||||
* Free Software Foundation, Inc.
|
|
||||||
* 51 Franklin Street, Fifth Floor
|
|
||||||
* Boston, MA 02110-1301 USA
|
|
||||||
*/
|
|
||||||
package org.hibernate.cache.internal.bridge;
|
|
||||||
|
|
||||||
import org.jboss.logging.Logger;
|
|
||||||
|
|
||||||
import org.hibernate.cache.CacheException;
|
|
||||||
import org.hibernate.cache.spi.Cache;
|
|
||||||
import org.hibernate.cache.spi.CacheConcurrencyStrategy;
|
|
||||||
import org.hibernate.cache.spi.CacheDataDescription;
|
|
||||||
import org.hibernate.cache.spi.EntityRegion;
|
|
||||||
import org.hibernate.cache.spi.NonstrictReadWriteCache;
|
|
||||||
import org.hibernate.cache.spi.OptimisticCache;
|
|
||||||
import org.hibernate.cache.spi.ReadOnlyCache;
|
|
||||||
import org.hibernate.cache.spi.ReadWriteCache;
|
|
||||||
import org.hibernate.cache.spi.TransactionalCache;
|
|
||||||
import org.hibernate.cache.spi.access.AccessType;
|
|
||||||
import org.hibernate.cache.spi.access.EntityRegionAccessStrategy;
|
|
||||||
import org.hibernate.cfg.Settings;
|
|
||||||
import org.hibernate.internal.CoreMessageLogger;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Adapter specifically bridging {@link EntityRegion} to {@link org.hibernate.cache.spi.Cache}.
|
|
||||||
*
|
|
||||||
* @author Steve Ebersole
|
|
||||||
*/
|
|
||||||
public class EntityRegionAdapter extends BaseTransactionalDataRegionAdapter implements EntityRegion {
|
|
||||||
|
|
||||||
private static final CoreMessageLogger LOG = Logger.getMessageLogger(CoreMessageLogger.class, EntityRegionAdapter.class.getName());
|
|
||||||
|
|
||||||
public EntityRegionAdapter(Cache underlyingCache, Settings settings, CacheDataDescription metadata) {
|
|
||||||
super( underlyingCache, settings, metadata );
|
|
||||||
if ( underlyingCache instanceof OptimisticCache ) {
|
|
||||||
( (OptimisticCache) underlyingCache ).setSource( new OptimisticCacheSourceAdapter( metadata ) );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public EntityRegionAccessStrategy buildAccessStrategy(AccessType accessType) throws CacheException {
|
|
||||||
CacheConcurrencyStrategy ccs;
|
|
||||||
if ( AccessType.READ_ONLY.equals( accessType ) ) {
|
|
||||||
if (metadata.isMutable()) LOG.readOnlyCacheConfiguredForMutableCollection(getName());
|
|
||||||
ccs = new ReadOnlyCache();
|
|
||||||
}
|
|
||||||
else if ( AccessType.READ_WRITE.equals( accessType ) ) {
|
|
||||||
ccs = new ReadWriteCache();
|
|
||||||
}
|
|
||||||
else if ( AccessType.NONSTRICT_READ_WRITE.equals( accessType ) ) {
|
|
||||||
ccs = new NonstrictReadWriteCache();
|
|
||||||
}
|
|
||||||
else if ( AccessType.TRANSACTIONAL.equals( accessType ) ) {
|
|
||||||
ccs = new TransactionalCache();
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
throw new IllegalArgumentException( "unrecognized access strategy type [" + accessType + "]" );
|
|
||||||
}
|
|
||||||
ccs.setCache( underlyingCache );
|
|
||||||
return new EntityAccessStrategyAdapter( this, ccs, settings );
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,125 +0,0 @@
|
||||||
/*
|
|
||||||
* Hibernate, Relational Persistence for Idiomatic Java
|
|
||||||
*
|
|
||||||
* Copyright (c) 2010, Red Hat Inc. or third-party contributors as
|
|
||||||
* indicated by the @author tags or express copyright attribution
|
|
||||||
* statements applied by the authors. All third-party contributions are
|
|
||||||
* distributed under license by Red Hat Inc.
|
|
||||||
*
|
|
||||||
* This copyrighted material is made available to anyone wishing to use, modify,
|
|
||||||
* copy, or redistribute it subject to the terms and conditions of the GNU
|
|
||||||
* Lesser General Public License, as published by the Free Software Foundation.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
|
||||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
|
||||||
* for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Lesser General Public License
|
|
||||||
* along with this distribution; if not, write to:
|
|
||||||
* Free Software Foundation, Inc.
|
|
||||||
* 51 Franklin Street, Fifth Floor
|
|
||||||
* Boston, MA 02110-1301 USA
|
|
||||||
*/
|
|
||||||
package org.hibernate.cache.internal.bridge;
|
|
||||||
|
|
||||||
import java.util.Properties;
|
|
||||||
|
|
||||||
import org.jboss.logging.Logger;
|
|
||||||
|
|
||||||
import org.hibernate.cache.CacheException;
|
|
||||||
import org.hibernate.cache.internal.NoCacheProvider;
|
|
||||||
import org.hibernate.cache.spi.CacheDataDescription;
|
|
||||||
import org.hibernate.cache.spi.CacheProvider;
|
|
||||||
import org.hibernate.cache.spi.CollectionRegion;
|
|
||||||
import org.hibernate.cache.spi.EntityRegion;
|
|
||||||
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.cfg.Environment;
|
|
||||||
import org.hibernate.cfg.Settings;
|
|
||||||
import org.hibernate.internal.CoreMessageLogger;
|
|
||||||
import org.hibernate.internal.util.ReflectHelper;
|
|
||||||
import org.hibernate.internal.util.config.ConfigurationHelper;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Acts as a bridge between the {@link RegionFactory} contract and the older
|
|
||||||
* {@link CacheProvider} contract.
|
|
||||||
*
|
|
||||||
* @author Steve Ebersole
|
|
||||||
*/
|
|
||||||
public class RegionFactoryCacheProviderBridge implements RegionFactory {
|
|
||||||
public static final String DEF_PROVIDER = NoCacheProvider.class.getName();
|
|
||||||
|
|
||||||
private static final CoreMessageLogger LOG = Logger.getMessageLogger(CoreMessageLogger.class,
|
|
||||||
RegionFactoryCacheProviderBridge.class.getName());
|
|
||||||
|
|
||||||
private CacheProvider cacheProvider;
|
|
||||||
private Settings settings;
|
|
||||||
|
|
||||||
public RegionFactoryCacheProviderBridge(Properties properties) {
|
|
||||||
String providerClassName = ConfigurationHelper.getString( Environment.CACHE_PROVIDER, properties, DEF_PROVIDER );
|
|
||||||
LOG.cacheProvider(providerClassName);
|
|
||||||
try {
|
|
||||||
cacheProvider = ( CacheProvider ) ReflectHelper.classForName( providerClassName ).newInstance();
|
|
||||||
}
|
|
||||||
catch ( Exception cnfe ) {
|
|
||||||
throw new CacheException( "could not instantiate CacheProvider [" + providerClassName + "]", cnfe );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void start(Settings settings, Properties properties) throws CacheException {
|
|
||||||
this.settings = settings;
|
|
||||||
cacheProvider.start( properties );
|
|
||||||
}
|
|
||||||
|
|
||||||
public void stop() {
|
|
||||||
cacheProvider.stop();
|
|
||||||
cacheProvider = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isMinimalPutsEnabledByDefault() {
|
|
||||||
return cacheProvider.isMinimalPutsEnabledByDefault();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* {@inheritDoc}
|
|
||||||
*/
|
|
||||||
public AccessType getDefaultAccessType() {
|
|
||||||
// we really have no idea
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public long nextTimestamp() {
|
|
||||||
return cacheProvider.nextTimestamp();
|
|
||||||
}
|
|
||||||
|
|
||||||
public CacheProvider getCacheProvider() {
|
|
||||||
return cacheProvider;
|
|
||||||
}
|
|
||||||
|
|
||||||
public EntityRegion buildEntityRegion(
|
|
||||||
String regionName,
|
|
||||||
Properties properties,
|
|
||||||
CacheDataDescription metadata) throws CacheException {
|
|
||||||
return new EntityRegionAdapter( cacheProvider.buildCache( regionName, properties ), settings, metadata );
|
|
||||||
}
|
|
||||||
|
|
||||||
public CollectionRegion buildCollectionRegion(
|
|
||||||
String regionName,
|
|
||||||
Properties properties,
|
|
||||||
CacheDataDescription metadata) throws CacheException {
|
|
||||||
return new CollectionRegionAdapter( cacheProvider.buildCache( regionName, properties ), settings, metadata );
|
|
||||||
}
|
|
||||||
|
|
||||||
public QueryResultsRegion buildQueryResultsRegion(String regionName, Properties properties) throws CacheException {
|
|
||||||
return new QueryResultsRegionAdapter( cacheProvider.buildCache( regionName, properties ), settings );
|
|
||||||
}
|
|
||||||
|
|
||||||
public TimestampsRegion buildTimestampsRegion(String regionName, Properties properties) throws CacheException {
|
|
||||||
return new TimestampsRegionAdapter( cacheProvider.buildCache( regionName, properties ), settings );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,39 +0,0 @@
|
||||||
/*
|
|
||||||
* Hibernate, Relational Persistence for Idiomatic Java
|
|
||||||
*
|
|
||||||
* Copyright (c) 2008-2011, Red Hat Inc. or third-party contributors as
|
|
||||||
* indicated by the @author tags or express copyright attribution
|
|
||||||
* statements applied by the authors. All third-party contributions are
|
|
||||||
* distributed under license by Red Hat Inc.
|
|
||||||
*
|
|
||||||
* This copyrighted material is made available to anyone wishing to use, modify,
|
|
||||||
* copy, or redistribute it subject to the terms and conditions of the GNU
|
|
||||||
* Lesser General Public License, as published by the Free Software Foundation.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
|
||||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
|
||||||
* for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Lesser General Public License
|
|
||||||
* along with this distribution; if not, write to:
|
|
||||||
* Free Software Foundation, Inc.
|
|
||||||
* 51 Franklin Street, Fifth Floor
|
|
||||||
* Boston, MA 02110-1301 USA
|
|
||||||
*/
|
|
||||||
package org.hibernate.cache.internal.bridge;
|
|
||||||
|
|
||||||
import org.hibernate.cache.spi.Cache;
|
|
||||||
import org.hibernate.cache.spi.TimestampsRegion;
|
|
||||||
import org.hibernate.cfg.Settings;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Adapter specifically bridging {@link TimestampsRegion} to {@link org.hibernate.cache.spi.Cache}.
|
|
||||||
*
|
|
||||||
* @author Steve Ebersole
|
|
||||||
*/
|
|
||||||
public class TimestampsRegionAdapter extends BaseGeneralDataRegionAdapter implements TimestampsRegion {
|
|
||||||
protected TimestampsRegionAdapter(Cache underlyingCache, Settings settings) {
|
|
||||||
super( underlyingCache, settings );
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,111 +0,0 @@
|
||||||
/*
|
|
||||||
* Hibernate, Relational Persistence for Idiomatic Java
|
|
||||||
*
|
|
||||||
* Copyright (c) 2008-2011, Red Hat Inc. or third-party contributors as
|
|
||||||
* indicated by the @author tags or express copyright attribution
|
|
||||||
* statements applied by the authors. All third-party contributions are
|
|
||||||
* distributed under license by Red Hat Inc.
|
|
||||||
*
|
|
||||||
* This copyrighted material is made available to anyone wishing to use, modify,
|
|
||||||
* copy, or redistribute it subject to the terms and conditions of the GNU
|
|
||||||
* Lesser General Public License, as published by the Free Software Foundation.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
|
||||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
|
||||||
* for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Lesser General Public License
|
|
||||||
* along with this distribution; if not, write to:
|
|
||||||
* Free Software Foundation, Inc.
|
|
||||||
* 51 Franklin Street, Fifth Floor
|
|
||||||
* Boston, MA 02110-1301 USA
|
|
||||||
*/
|
|
||||||
package org.hibernate.cache.spi;
|
|
||||||
|
|
||||||
import java.util.Properties;
|
|
||||||
import javax.naming.Context;
|
|
||||||
import javax.naming.InitialContext;
|
|
||||||
import javax.naming.NamingException;
|
|
||||||
|
|
||||||
import org.hibernate.cache.CacheException;
|
|
||||||
import org.hibernate.internal.CoreMessageLogger;
|
|
||||||
import org.hibernate.cfg.Environment;
|
|
||||||
import org.hibernate.internal.util.StringHelper;
|
|
||||||
import org.hibernate.internal.util.jndi.JndiHelper;
|
|
||||||
|
|
||||||
import org.jboss.logging.Logger;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Support for CacheProvider implementations which are backed by caches bound
|
|
||||||
* into JNDI namespace.
|
|
||||||
*
|
|
||||||
* @author Steve Ebersole
|
|
||||||
*/
|
|
||||||
public abstract class AbstractJndiBoundCacheProvider implements CacheProvider {
|
|
||||||
|
|
||||||
private static final CoreMessageLogger LOG = Logger.getMessageLogger(CoreMessageLogger.class,
|
|
||||||
AbstractJndiBoundCacheProvider.class.getName());
|
|
||||||
|
|
||||||
private Object cache;
|
|
||||||
|
|
||||||
protected void prepare(Properties properties) {
|
|
||||||
// Do nothing; subclasses may override.
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void release() {
|
|
||||||
// Do nothing; subclasses may override.
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Callback to perform any necessary initialization of the underlying cache implementation during SessionFactory
|
|
||||||
* construction.
|
|
||||||
*
|
|
||||||
* @param properties current configuration settings.
|
|
||||||
*/
|
|
||||||
public final void start(Properties properties) throws CacheException {
|
|
||||||
String jndiNamespace = properties.getProperty( Environment.CACHE_NAMESPACE );
|
|
||||||
if ( StringHelper.isEmpty( jndiNamespace ) ) {
|
|
||||||
throw new CacheException( "No JNDI namespace specified for cache" );
|
|
||||||
}
|
|
||||||
cache = locateCache( jndiNamespace, JndiHelper.extractJndiProperties( properties ) );
|
|
||||||
prepare( properties );
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Callback to perform any necessary cleanup of the underlying cache
|
|
||||||
* implementation during SessionFactory.close().
|
|
||||||
*/
|
|
||||||
public final void stop() {
|
|
||||||
release();
|
|
||||||
cache = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
private Object locateCache(String jndiNamespace, Properties jndiProperties) {
|
|
||||||
|
|
||||||
Context ctx = null;
|
|
||||||
try {
|
|
||||||
ctx = new InitialContext( jndiProperties );
|
|
||||||
return ctx.lookup( jndiNamespace );
|
|
||||||
}
|
|
||||||
catch (NamingException ne) {
|
|
||||||
String msg = "Unable to retreive Cache from JNDI [" + jndiNamespace + "]";
|
|
||||||
LOG.unableToRetrieveCache(jndiNamespace, ne.getMessage());
|
|
||||||
throw new CacheException( msg );
|
|
||||||
}
|
|
||||||
finally {
|
|
||||||
if ( ctx != null ) {
|
|
||||||
try {
|
|
||||||
ctx.close();
|
|
||||||
}
|
|
||||||
catch( NamingException ne ) {
|
|
||||||
LOG.unableToReleaseContext(ne.getMessage());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public Object getCache() {
|
|
||||||
return cache;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,132 +0,0 @@
|
||||||
/*
|
|
||||||
* Hibernate, Relational Persistence for Idiomatic Java
|
|
||||||
*
|
|
||||||
* Copyright (c) 2008-2011, Red Hat Inc. or third-party contributors as
|
|
||||||
* indicated by the @author tags or express copyright attribution
|
|
||||||
* statements applied by the authors. All third-party contributions are
|
|
||||||
* distributed under license by Red Hat Inc.
|
|
||||||
*
|
|
||||||
* This copyrighted material is made available to anyone wishing to use, modify,
|
|
||||||
* copy, or redistribute it subject to the terms and conditions of the GNU
|
|
||||||
* Lesser General Public License, as published by the Free Software Foundation.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
|
||||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
|
||||||
* for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Lesser General Public License
|
|
||||||
* along with this distribution; if not, write to:
|
|
||||||
* Free Software Foundation, Inc.
|
|
||||||
* 51 Franklin Street, Fifth Floor
|
|
||||||
* Boston, MA 02110-1301 USA
|
|
||||||
*/
|
|
||||||
package org.hibernate.cache.spi;
|
|
||||||
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
import org.hibernate.cache.CacheException;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Implementors define a caching algorithm. All implementors
|
|
||||||
* <b>must</b> be threadsafe.
|
|
||||||
*
|
|
||||||
* @deprecated As of 3.3; see <a href="package.html"/> for details.
|
|
||||||
*/
|
|
||||||
public interface Cache {
|
|
||||||
/**
|
|
||||||
* Get an item from the cache
|
|
||||||
* @param key
|
|
||||||
* @return the cached object or <tt>null</tt>
|
|
||||||
* @throws org.hibernate.cache.CacheException
|
|
||||||
*/
|
|
||||||
public Object read(Object key) throws CacheException;
|
|
||||||
/**
|
|
||||||
* Get an item from the cache, nontransactionally
|
|
||||||
* @param key
|
|
||||||
* @return the cached object or <tt>null</tt>
|
|
||||||
* @throws CacheException
|
|
||||||
*/
|
|
||||||
public Object get(Object key) throws CacheException;
|
|
||||||
/**
|
|
||||||
* Add an item to the cache, nontransactionally, with
|
|
||||||
* failfast semantics
|
|
||||||
* @param key
|
|
||||||
* @param value
|
|
||||||
* @throws CacheException
|
|
||||||
*/
|
|
||||||
public void put(Object key, Object value) throws CacheException;
|
|
||||||
/**
|
|
||||||
* Add an item to the cache
|
|
||||||
* @param key
|
|
||||||
* @param value
|
|
||||||
* @throws CacheException
|
|
||||||
*/
|
|
||||||
public void update(Object key, Object value) throws CacheException;
|
|
||||||
/**
|
|
||||||
* Remove an item from the cache
|
|
||||||
*/
|
|
||||||
public void remove(Object key) throws CacheException;
|
|
||||||
/**
|
|
||||||
* Clear the cache
|
|
||||||
*/
|
|
||||||
public void clear() throws CacheException;
|
|
||||||
/**
|
|
||||||
* Clean up
|
|
||||||
*/
|
|
||||||
public void destroy() throws CacheException;
|
|
||||||
/**
|
|
||||||
* If this is a clustered cache, lock the item
|
|
||||||
*/
|
|
||||||
public void lock(Object key) throws CacheException;
|
|
||||||
/**
|
|
||||||
* If this is a clustered cache, unlock the item
|
|
||||||
*/
|
|
||||||
public void unlock(Object key) throws CacheException;
|
|
||||||
/**
|
|
||||||
* Generate a timestamp
|
|
||||||
*/
|
|
||||||
public long nextTimestamp();
|
|
||||||
/**
|
|
||||||
* Get a reasonable "lock timeout"
|
|
||||||
*/
|
|
||||||
public int getTimeout();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the name of the cache region
|
|
||||||
*/
|
|
||||||
public String getRegionName();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The number of bytes is this cache region currently consuming in memory.
|
|
||||||
*
|
|
||||||
* @return The number of bytes consumed by this region; -1 if unknown or
|
|
||||||
* unsupported.
|
|
||||||
*/
|
|
||||||
public long getSizeInMemory();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The count of entries currently contained in the regions in-memory store.
|
|
||||||
*
|
|
||||||
* @return The count of entries in memory; -1 if unknown or unsupported.
|
|
||||||
*/
|
|
||||||
public long getElementCountInMemory();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The count of entries currently contained in the regions disk store.
|
|
||||||
*
|
|
||||||
* @return The count of entries on disk; -1 if unknown or unsupported.
|
|
||||||
*/
|
|
||||||
public long getElementCountOnDisk();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* optional operation
|
|
||||||
*/
|
|
||||||
public Map toMap();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,197 +0,0 @@
|
||||||
/*
|
|
||||||
* Hibernate, Relational Persistence for Idiomatic Java
|
|
||||||
*
|
|
||||||
* Copyright (c) 2008-2011, Red Hat Inc. or third-party contributors as
|
|
||||||
* indicated by the @author tags or express copyright attribution
|
|
||||||
* statements applied by the authors. All third-party contributions are
|
|
||||||
* distributed under license by Red Hat Inc.
|
|
||||||
*
|
|
||||||
* This copyrighted material is made available to anyone wishing to use, modify,
|
|
||||||
* copy, or redistribute it subject to the terms and conditions of the GNU
|
|
||||||
* Lesser General Public License, as published by the Free Software Foundation.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
|
||||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
|
||||||
* for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Lesser General Public License
|
|
||||||
* along with this distribution; if not, write to:
|
|
||||||
* Free Software Foundation, Inc.
|
|
||||||
* 51 Franklin Street, Fifth Floor
|
|
||||||
* Boston, MA 02110-1301 USA
|
|
||||||
*/
|
|
||||||
package org.hibernate.cache.spi;
|
|
||||||
|
|
||||||
import java.util.Comparator;
|
|
||||||
|
|
||||||
import org.hibernate.cache.CacheException;
|
|
||||||
import org.hibernate.cache.spi.access.SoftLock;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Implementors manage transactional access to cached data. Transactions
|
|
||||||
* pass in a timestamp indicating transaction start time. Two different
|
|
||||||
* implementation patterns are provided for.<ul>
|
|
||||||
* <li>A transaction-aware cache implementation might be wrapped by a
|
|
||||||
* "synchronous" concurrency strategy, where updates to the cache are written
|
|
||||||
* to the cache inside the transaction.</li>
|
|
||||||
* <li>A non transaction-aware cache would be wrapped by an "asynchronous"
|
|
||||||
* concurrency strategy, where items are merely "soft locked" during the
|
|
||||||
* transaction and then updated during the "after transaction completion"
|
|
||||||
* phase; the soft lock is not an actual lock on the database row -
|
|
||||||
* only upon the cached representation of the item.</li>
|
|
||||||
* </ul>
|
|
||||||
* <p/>
|
|
||||||
* In terms of entity caches, the expected call sequences are: <ul>
|
|
||||||
* <li><b>DELETES</b> : {@link #lock} -> {@link #evict} -> {@link #release}</li>
|
|
||||||
* <li><b>UPDATES</b> : {@link #lock} -> {@link #update} -> {@link #afterUpdate}</li>
|
|
||||||
* <li><b>INSERTS</b> : {@link #insert} -> {@link #afterInsert}</li>
|
|
||||||
* </ul>
|
|
||||||
* <p/>
|
|
||||||
* In terms of collection caches, all modification actions actually just
|
|
||||||
* invalidate the entry(s). The call sequence here is:
|
|
||||||
* {@link #lock} -> {@link #evict} -> {@link #release}
|
|
||||||
* <p/>
|
|
||||||
* Note that, for an asynchronous cache, cache invalidation must be a two
|
|
||||||
* step process (lock->release, or lock-afterUpdate), since this is the only
|
|
||||||
* way to guarantee consistency with the database for a nontransactional cache
|
|
||||||
* implementation. For a synchronous cache, cache invalidation is a single
|
|
||||||
* step process (evict, or update). Hence, this interface defines a three
|
|
||||||
* step process, to cater for both models.
|
|
||||||
* <p/>
|
|
||||||
* Note that query result caching does not go through a concurrency strategy; they
|
|
||||||
* are managed directly against the underlying {@link Cache cache regions}.
|
|
||||||
*
|
|
||||||
* @deprecated As of 3.3; see <a href="package.html"/> for details.
|
|
||||||
*/
|
|
||||||
public interface CacheConcurrencyStrategy {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Attempt to retrieve an object from the cache. Mainly used in attempting
|
|
||||||
* to resolve entities/collections from the second level cache.
|
|
||||||
*
|
|
||||||
* @param key
|
|
||||||
* @param txTimestamp a timestamp prior to the transaction start time
|
|
||||||
* @return the cached object or <tt>null</tt>
|
|
||||||
* @throws org.hibernate.cache.CacheException
|
|
||||||
*/
|
|
||||||
public Object get(Object key, long txTimestamp) throws CacheException;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Attempt to cache an object, after loading from the database.
|
|
||||||
*
|
|
||||||
* @param key
|
|
||||||
* @param value
|
|
||||||
* @param txTimestamp a timestamp prior to the transaction start time
|
|
||||||
* @param version the item version number
|
|
||||||
* @param versionComparator a comparator used to compare version numbers
|
|
||||||
* @param minimalPut indicates that the cache should avoid a put is the item is already cached
|
|
||||||
* @return <tt>true</tt> if the object was successfully cached
|
|
||||||
* @throws CacheException
|
|
||||||
*/
|
|
||||||
public boolean put(
|
|
||||||
Object key,
|
|
||||||
Object value,
|
|
||||||
long txTimestamp,
|
|
||||||
Object version,
|
|
||||||
Comparator versionComparator,
|
|
||||||
boolean minimalPut)
|
|
||||||
throws CacheException;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* We are going to attempt to update/delete the keyed object. This
|
|
||||||
* method is used by "asynchronous" concurrency strategies.
|
|
||||||
* <p/>
|
|
||||||
* The returned object must be passed back to release(), to release the
|
|
||||||
* lock. Concurrency strategies which do not support client-visible
|
|
||||||
* locks may silently return null.
|
|
||||||
*
|
|
||||||
* @param key
|
|
||||||
* @param version
|
|
||||||
* @throws CacheException
|
|
||||||
*/
|
|
||||||
public SoftLock lock(Object key, Object version) throws CacheException;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Called after an item has become stale (before the transaction completes).
|
|
||||||
* This method is used by "synchronous" concurrency strategies.
|
|
||||||
*/
|
|
||||||
public void evict(Object key) throws CacheException;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Called after an item has been updated (before the transaction completes),
|
|
||||||
* instead of calling evict().
|
|
||||||
* This method is used by "synchronous" concurrency strategies.
|
|
||||||
*/
|
|
||||||
public boolean update(Object key, Object value, Object currentVersion, Object previousVersion) throws CacheException;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Called after an item has been inserted (before the transaction completes),
|
|
||||||
* instead of calling evict().
|
|
||||||
* This method is used by "synchronous" concurrency strategies.
|
|
||||||
*/
|
|
||||||
public boolean insert(Object key, Object value, Object currentVersion) throws CacheException;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Called when we have finished the attempted update/delete (which may or
|
|
||||||
* may not have been successful), after transaction completion.
|
|
||||||
* This method is used by "asynchronous" concurrency strategies.
|
|
||||||
* @param key
|
|
||||||
* @throws CacheException
|
|
||||||
*/
|
|
||||||
public void release(Object key, SoftLock lock) throws CacheException;
|
|
||||||
/**
|
|
||||||
* Called after an item has been updated (after the transaction completes),
|
|
||||||
* instead of calling release().
|
|
||||||
* This method is used by "asynchronous" concurrency strategies.
|
|
||||||
*/
|
|
||||||
public boolean afterUpdate(Object key, Object value, Object version, SoftLock lock)
|
|
||||||
throws CacheException;
|
|
||||||
/**
|
|
||||||
* Called after an item has been inserted (after the transaction completes),
|
|
||||||
* instead of calling release().
|
|
||||||
* This method is used by "asynchronous" concurrency strategies.
|
|
||||||
*/
|
|
||||||
public boolean afterInsert(Object key, Object value, Object version)
|
|
||||||
throws CacheException;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Evict an item from the cache immediately (without regard for transaction
|
|
||||||
* isolation).
|
|
||||||
* @param key
|
|
||||||
* @throws CacheException
|
|
||||||
*/
|
|
||||||
public void remove(Object key) throws CacheException;
|
|
||||||
/**
|
|
||||||
* Evict all items from the cache immediately.
|
|
||||||
* @throws CacheException
|
|
||||||
*/
|
|
||||||
public void clear() throws CacheException;
|
|
||||||
/**
|
|
||||||
* Clean up all resources.
|
|
||||||
*/
|
|
||||||
public void destroy();
|
|
||||||
/**
|
|
||||||
* Set the underlying cache implementation.
|
|
||||||
* @param cache
|
|
||||||
*/
|
|
||||||
public void setCache(Cache cache);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the cache region name
|
|
||||||
*/
|
|
||||||
public String getRegionName();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the wrapped cache implementation
|
|
||||||
*/
|
|
||||||
public Cache getCache();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,68 +0,0 @@
|
||||||
/*
|
|
||||||
* Hibernate, Relational Persistence for Idiomatic Java
|
|
||||||
*
|
|
||||||
* Copyright (c) 2008-2011, Red Hat Inc. or third-party contributors as
|
|
||||||
* indicated by the @author tags or express copyright attribution
|
|
||||||
* statements applied by the authors. All third-party contributions are
|
|
||||||
* distributed under license by Red Hat Inc.
|
|
||||||
*
|
|
||||||
* This copyrighted material is made available to anyone wishing to use, modify,
|
|
||||||
* copy, or redistribute it subject to the terms and conditions of the GNU
|
|
||||||
* Lesser General Public License, as published by the Free Software Foundation.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
|
||||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
|
||||||
* for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Lesser General Public License
|
|
||||||
* along with this distribution; if not, write to:
|
|
||||||
* Free Software Foundation, Inc.
|
|
||||||
* 51 Franklin Street, Fifth Floor
|
|
||||||
* Boston, MA 02110-1301 USA
|
|
||||||
*/
|
|
||||||
package org.hibernate.cache.spi;
|
|
||||||
|
|
||||||
import java.util.Properties;
|
|
||||||
|
|
||||||
import org.hibernate.cache.CacheException;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Support for pluggable caches.
|
|
||||||
*
|
|
||||||
* @author Gavin King
|
|
||||||
* @deprecated As of 3.3; see <a href="package.html"/> for details.
|
|
||||||
*/
|
|
||||||
public interface CacheProvider {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Configure the cache
|
|
||||||
*
|
|
||||||
* @param regionName the name of the cache region
|
|
||||||
* @param properties configuration settings
|
|
||||||
* @throws org.hibernate.cache.CacheException
|
|
||||||
*/
|
|
||||||
public Cache buildCache(String regionName, Properties properties) throws CacheException;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Generate a timestamp
|
|
||||||
*/
|
|
||||||
public long nextTimestamp();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Callback to perform any necessary initialization of the underlying cache implementation
|
|
||||||
* during SessionFactory construction.
|
|
||||||
*
|
|
||||||
* @param properties current configuration settings.
|
|
||||||
*/
|
|
||||||
public void start(Properties properties) throws CacheException;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Callback to perform any necessary cleanup of the underlying cache implementation
|
|
||||||
* during SessionFactory.close().
|
|
||||||
*/
|
|
||||||
public void stop();
|
|
||||||
|
|
||||||
public boolean isMinimalPutsEnabledByDefault();
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,178 +0,0 @@
|
||||||
/*
|
|
||||||
* Hibernate, Relational Persistence for Idiomatic Java
|
|
||||||
*
|
|
||||||
* Copyright (c) 2008-2011, Red Hat Inc. or third-party contributors as
|
|
||||||
* indicated by the @author tags or express copyright attribution
|
|
||||||
* statements applied by the authors. All third-party contributions are
|
|
||||||
* distributed under license by Red Hat Inc.
|
|
||||||
*
|
|
||||||
* This copyrighted material is made available to anyone wishing to use, modify,
|
|
||||||
* copy, or redistribute it subject to the terms and conditions of the GNU
|
|
||||||
* Lesser General Public License, as published by the Free Software Foundation.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
|
||||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
|
||||||
* for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Lesser General Public License
|
|
||||||
* along with this distribution; if not, write to:
|
|
||||||
* Free Software Foundation, Inc.
|
|
||||||
* 51 Franklin Street, Fifth Floor
|
|
||||||
* Boston, MA 02110-1301 USA
|
|
||||||
*/
|
|
||||||
package org.hibernate.cache.spi;
|
|
||||||
|
|
||||||
import java.util.Comparator;
|
|
||||||
|
|
||||||
import org.jboss.logging.Logger;
|
|
||||||
|
|
||||||
import org.hibernate.cache.CacheException;
|
|
||||||
import org.hibernate.cache.spi.access.SoftLock;
|
|
||||||
import org.hibernate.internal.CoreMessageLogger;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Caches data that is sometimes updated without ever locking the cache.
|
|
||||||
* If concurrent access to an item is possible, this concurrency strategy
|
|
||||||
* makes no guarantee that the item returned from the cache is the latest
|
|
||||||
* version available in the database. Configure your cache timeout accordingly!
|
|
||||||
* This is an "asynchronous" concurrency strategy.
|
|
||||||
*
|
|
||||||
* @author Gavin King
|
|
||||||
* @see ReadWriteCache for a much stricter algorithm
|
|
||||||
*/
|
|
||||||
@Deprecated
|
|
||||||
public class NonstrictReadWriteCache implements CacheConcurrencyStrategy {
|
|
||||||
|
|
||||||
private static final CoreMessageLogger LOG = Logger.getMessageLogger(CoreMessageLogger.class,
|
|
||||||
NonstrictReadWriteCache.class.getName());
|
|
||||||
|
|
||||||
private Cache cache;
|
|
||||||
|
|
||||||
public NonstrictReadWriteCache() {
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setCache(Cache cache) {
|
|
||||||
this.cache = cache;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Cache getCache() {
|
|
||||||
return cache;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the most recent version, if available.
|
|
||||||
*/
|
|
||||||
public Object get(Object key, long txTimestamp) throws CacheException {
|
|
||||||
LOG.debugf("Cache lookup: %s", key);
|
|
||||||
|
|
||||||
Object result = cache.get( key );
|
|
||||||
if (result != null) LOG.debugf("Cache hit: %s", key);
|
|
||||||
else LOG.debugf("Cache miss: %s", key);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Add an item to the cache.
|
|
||||||
*/
|
|
||||||
public boolean put(
|
|
||||||
Object key,
|
|
||||||
Object value,
|
|
||||||
long txTimestamp,
|
|
||||||
Object version,
|
|
||||||
Comparator versionComparator,
|
|
||||||
boolean minimalPut) throws CacheException {
|
|
||||||
if ( minimalPut && cache.get( key ) != null ) {
|
|
||||||
LOG.debugf("Item already cached: %s", key);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
LOG.debugf("Caching: %s", key);
|
|
||||||
|
|
||||||
cache.put( key, value );
|
|
||||||
return true;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Do nothing.
|
|
||||||
*
|
|
||||||
* @return null, no lock
|
|
||||||
*/
|
|
||||||
public SoftLock lock(Object key, Object version) throws CacheException {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void remove(Object key) throws CacheException {
|
|
||||||
LOG.debugf("Removing: %s", key);
|
|
||||||
cache.remove( key );
|
|
||||||
}
|
|
||||||
|
|
||||||
public void clear() throws CacheException {
|
|
||||||
LOG.debugf("Clearing");
|
|
||||||
cache.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void destroy() {
|
|
||||||
try {
|
|
||||||
cache.destroy();
|
|
||||||
}
|
|
||||||
catch ( Exception e ) {
|
|
||||||
LOG.unableToDestroyCache(e.getMessage());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Invalidate the item
|
|
||||||
*/
|
|
||||||
public void evict(Object key) throws CacheException {
|
|
||||||
LOG.debugf("Invalidating: %s", key);
|
|
||||||
cache.remove( key );
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Invalidate the item
|
|
||||||
*/
|
|
||||||
public boolean insert(Object key, Object value, Object currentVersion) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Do nothing.
|
|
||||||
*/
|
|
||||||
public boolean update(Object key, Object value, Object currentVersion, Object previousVersion) {
|
|
||||||
evict( key );
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Invalidate the item (again, for safety).
|
|
||||||
*/
|
|
||||||
public void release(Object key, SoftLock lock) throws CacheException {
|
|
||||||
LOG.debugf("Invalidating: %s", key);
|
|
||||||
cache.remove( key );
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Invalidate the item (again, for safety).
|
|
||||||
*/
|
|
||||||
public boolean afterUpdate(Object key, Object value, Object version, SoftLock lock) throws CacheException {
|
|
||||||
release( key, lock );
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Do nothing.
|
|
||||||
*/
|
|
||||||
public boolean afterInsert(Object key, Object value, Object version) throws CacheException {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getRegionName() {
|
|
||||||
return cache.getRegionName();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return cache + "(nonstrict-read-write)";
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,87 +0,0 @@
|
||||||
/*
|
|
||||||
* Hibernate, Relational Persistence for Idiomatic Java
|
|
||||||
*
|
|
||||||
* Copyright (c) 2008-2011, Red Hat Inc. or third-party contributors as
|
|
||||||
* indicated by the @author tags or express copyright attribution
|
|
||||||
* statements applied by the authors. All third-party contributions are
|
|
||||||
* distributed under license by Red Hat Inc.
|
|
||||||
*
|
|
||||||
* This copyrighted material is made available to anyone wishing to use, modify,
|
|
||||||
* copy, or redistribute it subject to the terms and conditions of the GNU
|
|
||||||
* Lesser General Public License, as published by the Free Software Foundation.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
|
||||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
|
||||||
* for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Lesser General Public License
|
|
||||||
* along with this distribution; if not, write to:
|
|
||||||
* Free Software Foundation, Inc.
|
|
||||||
* 51 Franklin Street, Fifth Floor
|
|
||||||
* Boston, MA 02110-1301 USA
|
|
||||||
*/
|
|
||||||
package org.hibernate.cache.spi;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A contract for transactional cache implementations which support
|
|
||||||
* optimistic locking of items within the cache.
|
|
||||||
* <p/>
|
|
||||||
* The optimistic locking capabilities are only utilized for
|
|
||||||
* the entity cache regions.
|
|
||||||
* <p/>
|
|
||||||
* Unlike the methods on the {@link Cache} interface, all the methods
|
|
||||||
* here will only ever be called from access scenarios where versioned
|
|
||||||
* data is actually a possibility (i.e., entity data). Be sure to consult
|
|
||||||
* with {@link OptimisticCacheSource#isVersioned()} to determine whether
|
|
||||||
* versioning is actually in effect.
|
|
||||||
*
|
|
||||||
* @author Steve Ebersole
|
|
||||||
*/
|
|
||||||
public interface OptimisticCache extends Cache {
|
|
||||||
/**
|
|
||||||
* Indicates the "source" of the cached data. Currently this will
|
|
||||||
* only ever represent an {@link org.hibernate.persister.entity.EntityPersister}.
|
|
||||||
* <p/>
|
|
||||||
* Made available to the cache so that it can access certain information
|
|
||||||
* about versioning strategy.
|
|
||||||
*
|
|
||||||
* @param source The source.
|
|
||||||
*/
|
|
||||||
public void setSource(OptimisticCacheSource source);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Called during {@link CacheConcurrencyStrategy#insert} processing for
|
|
||||||
* transactional strategies. Indicates we have just performed an insert
|
|
||||||
* into the DB and now need to cache that entity's data.
|
|
||||||
*
|
|
||||||
* @param key The cache key.
|
|
||||||
* @param value The data to be cached.
|
|
||||||
* @param currentVersion The entity's version; or null if not versioned.
|
|
||||||
*/
|
|
||||||
public void writeInsert(Object key, Object value, Object currentVersion);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Called during {@link CacheConcurrencyStrategy#update} processing for
|
|
||||||
* transactional strategies. Indicates we have just performed an update
|
|
||||||
* against the DB and now need to cache the updated state.
|
|
||||||
*
|
|
||||||
* @param key The cache key.
|
|
||||||
* @param value The data to be cached.
|
|
||||||
* @param currentVersion The entity's current version
|
|
||||||
* @param previousVersion The entity's previous version (before the update);
|
|
||||||
* or null if not versioned.
|
|
||||||
*/
|
|
||||||
public void writeUpdate(Object key, Object value, Object currentVersion, Object previousVersion);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Called during {@link CacheConcurrencyStrategy#put} processing for
|
|
||||||
* transactional strategies. Indicates we have just loaded an entity's
|
|
||||||
* state from the database and need it cached.
|
|
||||||
*
|
|
||||||
* @param key The cache key.
|
|
||||||
* @param value The data to be cached.
|
|
||||||
* @param currentVersion The entity's version; or null if not versioned.
|
|
||||||
*/
|
|
||||||
public void writeLoad(Object key, Object value, Object currentVersion);
|
|
||||||
}
|
|
|
@ -1,165 +0,0 @@
|
||||||
/*
|
|
||||||
* Hibernate, Relational Persistence for Idiomatic Java
|
|
||||||
*
|
|
||||||
* Copyright (c) 2008-2011, Red Hat Inc. or third-party contributors as
|
|
||||||
* indicated by the @author tags or express copyright attribution
|
|
||||||
* statements applied by the authors. All third-party contributions are
|
|
||||||
* distributed under license by Red Hat Inc.
|
|
||||||
*
|
|
||||||
* This copyrighted material is made available to anyone wishing to use, modify,
|
|
||||||
* copy, or redistribute it subject to the terms and conditions of the GNU
|
|
||||||
* Lesser General Public License, as published by the Free Software Foundation.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
|
||||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
|
||||||
* for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Lesser General Public License
|
|
||||||
* along with this distribution; if not, write to:
|
|
||||||
* Free Software Foundation, Inc.
|
|
||||||
* 51 Franklin Street, Fifth Floor
|
|
||||||
* Boston, MA 02110-1301 USA
|
|
||||||
*/
|
|
||||||
package org.hibernate.cache.spi;
|
|
||||||
|
|
||||||
import java.util.Comparator;
|
|
||||||
|
|
||||||
import org.jboss.logging.Logger;
|
|
||||||
|
|
||||||
import org.hibernate.cache.CacheException;
|
|
||||||
import org.hibernate.cache.spi.access.SoftLock;
|
|
||||||
import org.hibernate.internal.CoreMessageLogger;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Caches data that is never updated.
|
|
||||||
* @see org.hibernate.cache.spi.CacheConcurrencyStrategy
|
|
||||||
*/
|
|
||||||
@Deprecated
|
|
||||||
public class ReadOnlyCache implements CacheConcurrencyStrategy {
|
|
||||||
|
|
||||||
private static final CoreMessageLogger LOG = Logger.getMessageLogger(CoreMessageLogger.class, ReadOnlyCache.class.getName());
|
|
||||||
|
|
||||||
private Cache cache;
|
|
||||||
|
|
||||||
public ReadOnlyCache() {}
|
|
||||||
|
|
||||||
public void setCache(Cache cache) {
|
|
||||||
this.cache=cache;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Cache getCache() {
|
|
||||||
return cache;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getRegionName() {
|
|
||||||
return cache.getRegionName();
|
|
||||||
}
|
|
||||||
|
|
||||||
public synchronized Object get(Object key, long timestamp) throws CacheException {
|
|
||||||
Object result = cache.get(key);
|
|
||||||
if (result != null) LOG.debugf("Cache hit: %s", key);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Unsupported!
|
|
||||||
*/
|
|
||||||
public SoftLock lock(Object key, Object version) {
|
|
||||||
LOG.invalidEditOfReadOnlyItem(key);
|
|
||||||
throw new UnsupportedOperationException("Can't write to a readonly object");
|
|
||||||
}
|
|
||||||
|
|
||||||
public synchronized boolean put(
|
|
||||||
Object key,
|
|
||||||
Object value,
|
|
||||||
long timestamp,
|
|
||||||
Object version,
|
|
||||||
Comparator versionComparator,
|
|
||||||
boolean minimalPut)
|
|
||||||
throws CacheException {
|
|
||||||
if ( minimalPut && cache.get(key)!=null ) {
|
|
||||||
LOG.debugf("Item already cached: %s", key);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
LOG.debugf("Caching: %s", key);
|
|
||||||
cache.put(key, value);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Unsupported!
|
|
||||||
*/
|
|
||||||
public void release(Object key, SoftLock lock) {
|
|
||||||
LOG.invalidEditOfReadOnlyItem(key);
|
|
||||||
//throw new UnsupportedOperationException("Can't write to a readonly object");
|
|
||||||
}
|
|
||||||
|
|
||||||
public void clear() throws CacheException {
|
|
||||||
cache.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void remove(Object key) throws CacheException {
|
|
||||||
cache.remove(key);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void destroy() {
|
|
||||||
try {
|
|
||||||
cache.destroy();
|
|
||||||
}
|
|
||||||
catch (Exception e) {
|
|
||||||
LOG.unableToDestroyCache(e.getMessage());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Unsupported!
|
|
||||||
*/
|
|
||||||
public boolean afterUpdate(Object key, Object value, Object version, SoftLock lock) throws CacheException {
|
|
||||||
LOG.invalidEditOfReadOnlyItem(key);
|
|
||||||
throw new UnsupportedOperationException("Can't write to a readonly object");
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Do nothing.
|
|
||||||
*/
|
|
||||||
public boolean afterInsert(Object key, Object value, Object version) throws CacheException {
|
|
||||||
LOG.debugf("Caching after insert: %s", key);
|
|
||||||
cache.update(key, value);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Do nothing.
|
|
||||||
*/
|
|
||||||
public void evict(Object key) throws CacheException {
|
|
||||||
// noop
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Do nothing.
|
|
||||||
*/
|
|
||||||
public boolean insert(Object key, Object value, Object currentVersion) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Unsupported!
|
|
||||||
*/
|
|
||||||
public boolean update(Object key, Object value, Object currentVersion, Object previousVersion) {
|
|
||||||
LOG.invalidEditOfReadOnlyItem(key);
|
|
||||||
throw new UnsupportedOperationException("Can't write to a readonly object");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return cache + "(read-only)";
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,500 +0,0 @@
|
||||||
/*
|
|
||||||
* Hibernate, Relational Persistence for Idiomatic Java
|
|
||||||
*
|
|
||||||
* Copyright (c) 2008-2011, Red Hat Inc. or third-party contributors as
|
|
||||||
* indicated by the @author tags or express copyright attribution
|
|
||||||
* statements applied by the authors. All third-party contributions are
|
|
||||||
* distributed under license by Red Hat Inc.
|
|
||||||
*
|
|
||||||
* This copyrighted material is made available to anyone wishing to use, modify,
|
|
||||||
* copy, or redistribute it subject to the terms and conditions of the GNU
|
|
||||||
* Lesser General Public License, as published by the Free Software Foundation.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
|
||||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
|
||||||
* for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Lesser General Public License
|
|
||||||
* along with this distribution; if not, write to:
|
|
||||||
* Free Software Foundation, Inc.
|
|
||||||
* 51 Franklin Street, Fifth Floor
|
|
||||||
* Boston, MA 02110-1301 USA
|
|
||||||
*/
|
|
||||||
package org.hibernate.cache.spi;
|
|
||||||
|
|
||||||
import java.io.Serializable;
|
|
||||||
import java.util.Comparator;
|
|
||||||
|
|
||||||
import org.jboss.logging.Logger;
|
|
||||||
|
|
||||||
import org.hibernate.cache.CacheException;
|
|
||||||
import org.hibernate.cache.spi.access.SoftLock;
|
|
||||||
import org.hibernate.internal.CoreMessageLogger;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Caches data that is sometimes updated while maintaining the semantics of
|
|
||||||
* "read committed" isolation level. If the database is set to "repeatable
|
|
||||||
* read", this concurrency strategy <em>almost</em> maintains the semantics.
|
|
||||||
* Repeatable read isolation is compromised in the case of concurrent writes.
|
|
||||||
* This is an "asynchronous" concurrency strategy.<br>
|
|
||||||
* <br>
|
|
||||||
* If this strategy is used in a cluster, the underlying cache implementation
|
|
||||||
* must support distributed hard locks (which are held only momentarily). This
|
|
||||||
* strategy also assumes that the underlying cache implementation does not do
|
|
||||||
* asynchronous replication and that state has been fully replicated as soon
|
|
||||||
* as the lock is released.
|
|
||||||
*
|
|
||||||
* @see NonstrictReadWriteCache for a faster algorithm
|
|
||||||
* @see org.hibernate.cache.spi.CacheConcurrencyStrategy
|
|
||||||
*/
|
|
||||||
@Deprecated
|
|
||||||
public class ReadWriteCache implements CacheConcurrencyStrategy {
|
|
||||||
|
|
||||||
private static final CoreMessageLogger LOG = Logger.getMessageLogger(CoreMessageLogger.class, ReadWriteCache.class.getName());
|
|
||||||
|
|
||||||
private Cache cache;
|
|
||||||
private int nextLockId;
|
|
||||||
|
|
||||||
public ReadWriteCache() {}
|
|
||||||
|
|
||||||
public void setCache(Cache cache) {
|
|
||||||
this.cache=cache;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Cache getCache() {
|
|
||||||
return cache;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getRegionName() {
|
|
||||||
return cache.getRegionName();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Generate an id for a new lock. Uniqueness per cache instance is very
|
|
||||||
* desirable but not absolutely critical. Must be called from one of the
|
|
||||||
* synchronized methods of this class.
|
|
||||||
*/
|
|
||||||
private int nextLockId() {
|
|
||||||
if (nextLockId==Integer.MAX_VALUE) nextLockId = Integer.MIN_VALUE;
|
|
||||||
return nextLockId++;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Do not return an item whose timestamp is later than the current
|
|
||||||
* transaction timestamp. (Otherwise we might compromise repeatable
|
|
||||||
* read unnecessarily.) Do not return an item which is soft-locked.
|
|
||||||
* Always go straight to the database instead.<br>
|
|
||||||
* <br>
|
|
||||||
* Note that since reading an item from that cache does not actually
|
|
||||||
* go to the database, it is possible to see a kind of phantom read
|
|
||||||
* due to the underlying row being updated after we have read it
|
|
||||||
* from the cache. This would not be possible in a lock-based
|
|
||||||
* implementation of repeatable read isolation. It is also possible
|
|
||||||
* to overwrite changes made and committed by another transaction
|
|
||||||
* after the current transaction read the item from the cache. This
|
|
||||||
* problem would be caught by the update-time version-checking, if
|
|
||||||
* the data is versioned or timestamped.
|
|
||||||
*/
|
|
||||||
public synchronized Object get(Object key, long txTimestamp) throws CacheException {
|
|
||||||
LOG.debugf("Cache lookup: %s", key);
|
|
||||||
Lockable lockable = (Lockable)cache.get(key);
|
|
||||||
boolean gettable = lockable != null && lockable.isGettable(txTimestamp);
|
|
||||||
if (gettable) {
|
|
||||||
LOG.debugf("Cache hit: %s", key);
|
|
||||||
return ((Item)lockable).getValue();
|
|
||||||
}
|
|
||||||
if (lockable == null) LOG.debugf("Cache miss: %s", key);
|
|
||||||
else LOG.debugf("Cached item was locked: %s", key);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Stop any other transactions reading or writing this item to/from
|
|
||||||
* the cache. Send them straight to the database instead. (The lock
|
|
||||||
* does time out eventually.) This implementation tracks concurrent
|
|
||||||
* locks of transactions which simultaneously attempt to write to an
|
|
||||||
* item.
|
|
||||||
*/
|
|
||||||
public synchronized SoftLock lock(Object key, Object version) throws CacheException {
|
|
||||||
LOG.debugf("Invalidating: %s", key);
|
|
||||||
try {
|
|
||||||
cache.lock(key);
|
|
||||||
|
|
||||||
Lockable lockable = (Lockable) cache.get(key);
|
|
||||||
long timeout = cache.nextTimestamp() + cache.getTimeout();
|
|
||||||
final Lock lock = (lockable==null) ?
|
|
||||||
new Lock( timeout, nextLockId(), version ) :
|
|
||||||
lockable.lock( timeout, nextLockId() );
|
|
||||||
cache.update(key, lock);
|
|
||||||
return lock;
|
|
||||||
}
|
|
||||||
finally {
|
|
||||||
cache.unlock(key);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Do not add an item to the cache unless the current transaction
|
|
||||||
* timestamp is later than the timestamp at which the item was
|
|
||||||
* invalidated. (Otherwise, a stale item might be re-added if the
|
|
||||||
* database is operating in repeatable read isolation mode.)
|
|
||||||
* For versioned data, don't add the item unless it is the later
|
|
||||||
* version.
|
|
||||||
*/
|
|
||||||
public synchronized boolean put(
|
|
||||||
Object key,
|
|
||||||
Object value,
|
|
||||||
long txTimestamp,
|
|
||||||
Object version,
|
|
||||||
Comparator versionComparator,
|
|
||||||
boolean minimalPut)
|
|
||||||
throws CacheException {
|
|
||||||
LOG.debugf("Caching: %s", key);
|
|
||||||
|
|
||||||
try {
|
|
||||||
cache.lock(key);
|
|
||||||
|
|
||||||
Lockable lockable = (Lockable) cache.get(key);
|
|
||||||
|
|
||||||
boolean puttable = lockable==null ||
|
|
||||||
lockable.isPuttable(txTimestamp, version, versionComparator);
|
|
||||||
|
|
||||||
if (puttable) {
|
|
||||||
cache.put( key, new Item( value, version, cache.nextTimestamp() ) );
|
|
||||||
LOG.debugf("Cached: %s", key);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (lockable.isLock()) LOG.debugf("Cached item was locked: %s", key);
|
|
||||||
else LOG.debugf("Item already cached: %s", key);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
finally {
|
|
||||||
cache.unlock(key);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* decrement a lock and put it back in the cache
|
|
||||||
*/
|
|
||||||
private void decrementLock(Object key, Lock lock) throws CacheException {
|
|
||||||
//decrement the lock
|
|
||||||
lock.unlock( cache.nextTimestamp() );
|
|
||||||
cache.update(key, lock);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Release the soft lock on the item. Other transactions may now
|
|
||||||
* re-cache the item (assuming that no other transaction holds a
|
|
||||||
* simultaneous lock).
|
|
||||||
*/
|
|
||||||
public synchronized void release(Object key, SoftLock clientLock) throws CacheException {
|
|
||||||
LOG.debugf("Releasing: %s", key);
|
|
||||||
|
|
||||||
try {
|
|
||||||
cache.lock(key);
|
|
||||||
|
|
||||||
Lockable lockable = (Lockable) cache.get(key);
|
|
||||||
if ( isUnlockable(clientLock, lockable) ) {
|
|
||||||
decrementLock(key, (Lock) lockable);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
handleLockExpiry(key);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
finally {
|
|
||||||
cache.unlock(key);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void handleLockExpiry(Object key) throws CacheException {
|
|
||||||
LOG.expired(key);
|
|
||||||
long ts = cache.nextTimestamp() + cache.getTimeout();
|
|
||||||
// create new lock that times out immediately
|
|
||||||
Lock lock = new Lock( ts, nextLockId(), null );
|
|
||||||
lock.unlock(ts);
|
|
||||||
cache.update(key, lock);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void clear() throws CacheException {
|
|
||||||
cache.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void remove(Object key) throws CacheException {
|
|
||||||
cache.remove(key);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void destroy() {
|
|
||||||
try {
|
|
||||||
cache.destroy();
|
|
||||||
}
|
|
||||||
catch (Exception e) {
|
|
||||||
LOG.unableToDestroyCache(e.getMessage());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Re-cache the updated state, if and only if there there are
|
|
||||||
* no other concurrent soft locks. Release our lock.
|
|
||||||
*/
|
|
||||||
public synchronized boolean afterUpdate(Object key, Object value, Object version, SoftLock clientLock)
|
|
||||||
throws CacheException {
|
|
||||||
|
|
||||||
LOG.debugf("Updating: %s", key);
|
|
||||||
|
|
||||||
try {
|
|
||||||
cache.lock(key);
|
|
||||||
|
|
||||||
Lockable lockable = (Lockable) cache.get(key);
|
|
||||||
if ( isUnlockable(clientLock, lockable) ) {
|
|
||||||
Lock lock = (Lock) lockable;
|
|
||||||
if ( lock.wasLockedConcurrently() ) {
|
|
||||||
// just decrement the lock, don't recache
|
|
||||||
// (we don't know which transaction won)
|
|
||||||
decrementLock(key, lock);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
// recache the updated state
|
|
||||||
cache.update(key, new Item(value, version, cache.nextTimestamp()));
|
|
||||||
LOG.debugf("Updated: %s", key);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
handleLockExpiry(key);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
finally {
|
|
||||||
cache.unlock(key);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Add the new item to the cache, checking that no other transaction has
|
|
||||||
* accessed the item.
|
|
||||||
*/
|
|
||||||
public synchronized boolean afterInsert(Object key, Object value, Object version)
|
|
||||||
throws CacheException {
|
|
||||||
|
|
||||||
LOG.debugf("Inserting: %s", key);
|
|
||||||
try {
|
|
||||||
cache.lock(key);
|
|
||||||
|
|
||||||
Lockable lockable = (Lockable) cache.get(key);
|
|
||||||
if (lockable==null) {
|
|
||||||
cache.update( key, new Item( value, version, cache.nextTimestamp() ) );
|
|
||||||
LOG.debugf("Inserted: %s", key);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
finally {
|
|
||||||
cache.unlock(key);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Do nothing.
|
|
||||||
*/
|
|
||||||
public void evict(Object key) throws CacheException {
|
|
||||||
// noop
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Do nothing.
|
|
||||||
*/
|
|
||||||
public boolean insert(Object key, Object value, Object currentVersion) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Do nothing.
|
|
||||||
*/
|
|
||||||
public boolean update(Object key, Object value, Object currentVersion, Object previousVersion) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Is the client's lock commensurate with the item in the cache?
|
|
||||||
* If it is not, we know that the cache expired the original
|
|
||||||
* lock.
|
|
||||||
*/
|
|
||||||
private boolean isUnlockable(SoftLock clientLock, Lockable myLock)
|
|
||||||
throws CacheException {
|
|
||||||
//null clientLock is remotely possible but will never happen in practice
|
|
||||||
return myLock!=null &&
|
|
||||||
myLock.isLock() &&
|
|
||||||
clientLock!=null &&
|
|
||||||
( (Lock) clientLock ).getId()==( (Lock) myLock ).getId();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static interface Lockable {
|
|
||||||
public Lock lock(long timeout, int id);
|
|
||||||
public boolean isLock();
|
|
||||||
public boolean isGettable(long txTimestamp);
|
|
||||||
public boolean isPuttable(long txTimestamp, Object newVersion, Comparator comparator);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* An item of cached data, timestamped with the time it was cached,.
|
|
||||||
* @see ReadWriteCache
|
|
||||||
*/
|
|
||||||
public static final class Item implements Serializable, Lockable {
|
|
||||||
|
|
||||||
private final long freshTimestamp;
|
|
||||||
private final Object value;
|
|
||||||
private final Object version;
|
|
||||||
|
|
||||||
public Item(Object value, Object version, long currentTimestamp) {
|
|
||||||
this.value = value;
|
|
||||||
this.version = version;
|
|
||||||
freshTimestamp = currentTimestamp;
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* The timestamp on the cached data
|
|
||||||
*/
|
|
||||||
public long getFreshTimestamp() {
|
|
||||||
return freshTimestamp;
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* The actual cached data
|
|
||||||
*/
|
|
||||||
public Object getValue() {
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Lock the item
|
|
||||||
*/
|
|
||||||
public Lock lock(long timeout, int id) {
|
|
||||||
return new Lock(timeout, id, version);
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* Not a lock!
|
|
||||||
*/
|
|
||||||
public boolean isLock() {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* Is this item visible to the timestamped
|
|
||||||
* transaction?
|
|
||||||
*/
|
|
||||||
public boolean isGettable(long txTimestamp) {
|
|
||||||
return freshTimestamp < txTimestamp;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Don't overwite already cached items
|
|
||||||
*/
|
|
||||||
public boolean isPuttable(long txTimestamp, Object newVersion, Comparator comparator) {
|
|
||||||
// we really could refresh the item if it
|
|
||||||
// is not a lock, but it might be slower
|
|
||||||
//return freshTimestamp < txTimestamp
|
|
||||||
return version!=null && comparator.compare(version, newVersion) < 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return "Item{version=" + version +
|
|
||||||
",freshTimestamp=" + freshTimestamp;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A soft lock which supports concurrent locking,
|
|
||||||
* timestamped with the time it was released
|
|
||||||
* @author Gavin King
|
|
||||||
*/
|
|
||||||
public static final class Lock implements Serializable, Lockable, SoftLock {
|
|
||||||
private long unlockTimestamp = -1;
|
|
||||||
private int multiplicity = 1;
|
|
||||||
private boolean concurrentLock = false;
|
|
||||||
private long timeout;
|
|
||||||
private final int id;
|
|
||||||
private final Object version;
|
|
||||||
|
|
||||||
public Lock(long timeout, int id, Object version) {
|
|
||||||
this.timeout = timeout;
|
|
||||||
this.id = id;
|
|
||||||
this.version = version;
|
|
||||||
}
|
|
||||||
|
|
||||||
public long getUnlockTimestamp() {
|
|
||||||
return unlockTimestamp;
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* Increment the lock, setting the
|
|
||||||
* new lock timeout
|
|
||||||
*/
|
|
||||||
public Lock lock(long timeout, int id) {
|
|
||||||
concurrentLock = true;
|
|
||||||
multiplicity++;
|
|
||||||
this.timeout = timeout;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* Decrement the lock, setting the unlock
|
|
||||||
* timestamp if now unlocked
|
|
||||||
* @param currentTimestamp
|
|
||||||
*/
|
|
||||||
public void unlock(long currentTimestamp) {
|
|
||||||
if ( --multiplicity == 0 ) {
|
|
||||||
unlockTimestamp = currentTimestamp;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Can the timestamped transaction re-cache this
|
|
||||||
* locked item now?
|
|
||||||
*/
|
|
||||||
public boolean isPuttable(long txTimestamp, Object newVersion, Comparator comparator) {
|
|
||||||
if (timeout < txTimestamp) return true;
|
|
||||||
if (multiplicity>0) return false;
|
|
||||||
return version==null ?
|
|
||||||
unlockTimestamp < txTimestamp :
|
|
||||||
comparator.compare(version, newVersion) < 0; //by requiring <, we rely on lock timeout in the case of an unsuccessful update!
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Was this lock held concurrently by multiple
|
|
||||||
* transactions?
|
|
||||||
*/
|
|
||||||
public boolean wasLockedConcurrently() {
|
|
||||||
return concurrentLock;
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* Yes, this is a lock
|
|
||||||
*/
|
|
||||||
public boolean isLock() {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* locks are not returned to the client!
|
|
||||||
*/
|
|
||||||
public boolean isGettable(long txTimestamp) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getId() { return id; }
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return "Lock{id=" + id +
|
|
||||||
",version=" + version +
|
|
||||||
",multiplicity=" + multiplicity +
|
|
||||||
",unlockTimestamp=" + unlockTimestamp;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return cache + "(read-write)";
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -38,12 +38,7 @@ import org.hibernate.service.Service;
|
||||||
* <li>MyRegionFactoryImpl()</li>
|
* <li>MyRegionFactoryImpl()</li>
|
||||||
* </ul>
|
* </ul>
|
||||||
* Use the first when we need to read config properties prior to
|
* Use the first when we need to read config properties prior to
|
||||||
* {@link #start(Settings, Properties)} being called. For an example, have a look at
|
* {@link #start(Settings, Properties)} being called.
|
||||||
* {@link org.hibernate.cache.internal.bridge.RegionFactoryCacheProviderBridge}
|
|
||||||
* where we need the properties in order to determine which legacy
|
|
||||||
* {@link CacheProvider} to use so that we can answer the
|
|
||||||
* {@link #isMinimalPutsEnabledByDefault()} question for the
|
|
||||||
* {@link org.hibernate.cfg.SettingsFactory}.
|
|
||||||
*
|
*
|
||||||
* @author Steve Ebersole
|
* @author Steve Ebersole
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -1,183 +0,0 @@
|
||||||
/*
|
|
||||||
* Hibernate, Relational Persistence for Idiomatic Java
|
|
||||||
*
|
|
||||||
* Copyright (c) 2008-2011, Red Hat Inc. or third-party contributors as
|
|
||||||
* indicated by the @author tags or express copyright attribution
|
|
||||||
* statements applied by the authors. All third-party contributions are
|
|
||||||
* distributed under license by Red Hat Inc.
|
|
||||||
*
|
|
||||||
* This copyrighted material is made available to anyone wishing to use, modify,
|
|
||||||
* copy, or redistribute it subject to the terms and conditions of the GNU
|
|
||||||
* Lesser General Public License, as published by the Free Software Foundation.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
|
||||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
|
||||||
* for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Lesser General Public License
|
|
||||||
* along with this distribution; if not, write to:
|
|
||||||
* Free Software Foundation, Inc.
|
|
||||||
* 51 Franklin Street, Fifth Floor
|
|
||||||
* Boston, MA 02110-1301 USA
|
|
||||||
*/
|
|
||||||
package org.hibernate.cache.spi;
|
|
||||||
|
|
||||||
import java.util.Comparator;
|
|
||||||
|
|
||||||
import org.jboss.logging.Logger;
|
|
||||||
|
|
||||||
import org.hibernate.cache.CacheException;
|
|
||||||
import org.hibernate.cache.spi.access.SoftLock;
|
|
||||||
import org.hibernate.internal.CoreMessageLogger;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Support for fully transactional cache implementations like
|
|
||||||
* JBoss TreeCache. Note that this might be a less scalable
|
|
||||||
* concurrency strategy than <tt>ReadWriteCache</tt>. This is
|
|
||||||
* a "synchronous" concurrency strategy.
|
|
||||||
*
|
|
||||||
* @author Gavin King
|
|
||||||
*/
|
|
||||||
@Deprecated
|
|
||||||
public class TransactionalCache implements CacheConcurrencyStrategy {
|
|
||||||
|
|
||||||
private static final CoreMessageLogger LOG = Logger.getMessageLogger(CoreMessageLogger.class, TransactionalCache.class.getName());
|
|
||||||
|
|
||||||
private Cache cache;
|
|
||||||
|
|
||||||
public String getRegionName() {
|
|
||||||
return cache.getRegionName();
|
|
||||||
}
|
|
||||||
|
|
||||||
public Object get(Object key, long txTimestamp) throws CacheException {
|
|
||||||
LOG.debugf("Cache lookup: %s", key);
|
|
||||||
Object result = cache.read( key );
|
|
||||||
if (result == null) LOG.debugf("Cache miss: %s", key);
|
|
||||||
else LOG.debugf("Cache hit: %s", key);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean put(
|
|
||||||
Object key,
|
|
||||||
Object value,
|
|
||||||
long txTimestamp,
|
|
||||||
Object version,
|
|
||||||
Comparator versionComparator,
|
|
||||||
boolean minimalPut) throws CacheException {
|
|
||||||
if ( minimalPut && cache.read( key ) != null ) {
|
|
||||||
LOG.debugf("Item already cached: %s", key);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
LOG.debugf("Caching: %s", key);
|
|
||||||
if ( cache instanceof OptimisticCache ) {
|
|
||||||
( ( OptimisticCache ) cache ).writeLoad( key, value, version );
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
cache.put( key, value );
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Do nothing, returning null.
|
|
||||||
*/
|
|
||||||
public SoftLock lock(Object key, Object version) throws CacheException {
|
|
||||||
//noop
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Do nothing.
|
|
||||||
*/
|
|
||||||
public void release(Object key, SoftLock clientLock) throws CacheException {
|
|
||||||
//noop
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean update(
|
|
||||||
Object key,
|
|
||||||
Object value,
|
|
||||||
Object currentVersion,
|
|
||||||
Object previousVersion) throws CacheException {
|
|
||||||
LOG.debugf("Updating: %s", key);
|
|
||||||
if ( cache instanceof OptimisticCache ) {
|
|
||||||
( ( OptimisticCache ) cache ).writeUpdate( key, value, currentVersion, previousVersion );
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
cache.update( key, value );
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean insert(
|
|
||||||
Object key,
|
|
||||||
Object value,
|
|
||||||
Object currentVersion) throws CacheException {
|
|
||||||
LOG.debugf("Inserting: %s", key);
|
|
||||||
if ( cache instanceof OptimisticCache ) {
|
|
||||||
( ( OptimisticCache ) cache ).writeInsert( key, value, currentVersion );
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
cache.update( key, value );
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void evict(Object key) throws CacheException {
|
|
||||||
cache.remove( key );
|
|
||||||
}
|
|
||||||
|
|
||||||
public void remove(Object key) throws CacheException {
|
|
||||||
LOG.debugf("Removing: %s", key);
|
|
||||||
cache.remove( key );
|
|
||||||
}
|
|
||||||
|
|
||||||
public void clear() throws CacheException {
|
|
||||||
LOG.debugf("Clearing");
|
|
||||||
cache.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void destroy() {
|
|
||||||
try {
|
|
||||||
cache.destroy();
|
|
||||||
}
|
|
||||||
catch ( Exception e ) {
|
|
||||||
LOG.unableToDestroyCache(e.getMessage());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setCache(Cache cache) {
|
|
||||||
this.cache = cache;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Cache getCache() {
|
|
||||||
return cache;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Do nothing.
|
|
||||||
*/
|
|
||||||
public boolean afterInsert(
|
|
||||||
Object key,
|
|
||||||
Object value,
|
|
||||||
Object version) throws CacheException {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Do nothing.
|
|
||||||
*/
|
|
||||||
public boolean afterUpdate(
|
|
||||||
Object key,
|
|
||||||
Object value,
|
|
||||||
Object version,
|
|
||||||
SoftLock clientLock) throws CacheException {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return cache + "(transactional)";
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -104,37 +104,4 @@ public interface EntityRegionAccessStrategy extends RegionAccessStrategy{
|
||||||
* @throws CacheException Propogated from underlying {@link org.hibernate.cache.spi.Region}
|
* @throws CacheException Propogated from underlying {@link org.hibernate.cache.spi.Region}
|
||||||
*/
|
*/
|
||||||
public boolean afterUpdate(Object key, Object value, Object currentVersion, Object previousVersion, SoftLock lock) throws CacheException;
|
public boolean afterUpdate(Object key, Object value, Object currentVersion, Object previousVersion, SoftLock lock) throws CacheException;
|
||||||
|
|
||||||
/**
|
|
||||||
* Called after an item has become stale (before the transaction completes).
|
|
||||||
* This method is used by "synchronous" concurrency strategies.
|
|
||||||
*
|
|
||||||
* @param key The key of the item to remove
|
|
||||||
* @throws CacheException Propogated from underlying {@link org.hibernate.cache.spi.Region}
|
|
||||||
*/
|
|
||||||
public void remove(Object key) throws CacheException;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Called to evict data from the entire region
|
|
||||||
*
|
|
||||||
* @throws CacheException Propogated from underlying {@link org.hibernate.cache.spi.Region}
|
|
||||||
*/
|
|
||||||
public void removeAll() throws CacheException;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Forcibly evict an item from the cache immediately without regard for transaction
|
|
||||||
* isolation.
|
|
||||||
*
|
|
||||||
* @param key The key of the item to remove
|
|
||||||
* @throws CacheException Propogated from underlying {@link org.hibernate.cache.spi.Region}
|
|
||||||
*/
|
|
||||||
public void evict(Object key) throws CacheException;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Forcibly evict all items from the cache immediately without regard for transaction
|
|
||||||
* isolation.
|
|
||||||
*
|
|
||||||
* @throws CacheException Propogated from underlying {@link org.hibernate.cache.spi.Region}
|
|
||||||
*/
|
|
||||||
public void evictAll() throws CacheException;
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -288,13 +288,6 @@ public interface AvailableSettings {
|
||||||
@Deprecated
|
@Deprecated
|
||||||
public static final String USER_TRANSACTION = "jta.UserTransaction";
|
public static final String USER_TRANSACTION = "jta.UserTransaction";
|
||||||
|
|
||||||
/**
|
|
||||||
* The <tt>CacheProvider</tt> implementation class
|
|
||||||
*
|
|
||||||
* @deprecated See {@link #CACHE_REGION_FACTORY}
|
|
||||||
*/
|
|
||||||
public static final String CACHE_PROVIDER = "hibernate.cache.provider_class";
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The {@link org.hibernate.cache.spi.RegionFactory} implementation class
|
* The {@link org.hibernate.cache.spi.RegionFactory} implementation class
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -75,11 +75,6 @@ import org.hibernate.internal.util.config.ConfigurationHelper;
|
||||||
* <td>classname of <tt>org.hibernate.dialect.Dialect</tt> subclass</td>
|
* <td>classname of <tt>org.hibernate.dialect.Dialect</tt> subclass</td>
|
||||||
* </tr>
|
* </tr>
|
||||||
* <tr>
|
* <tr>
|
||||||
* <td><tt>hibernate.cache.provider_class</tt></td>
|
|
||||||
* <td>classname of <tt>org.hibernate.cache.spi.CacheProvider</tt>
|
|
||||||
* subclass (if not specified EHCache is used)</td>
|
|
||||||
* </tr>
|
|
||||||
* <tr>
|
|
||||||
* <td><tt>hibernate.connection.provider_class</tt></td>
|
* <td><tt>hibernate.connection.provider_class</tt></td>
|
||||||
* <td>classname of <tt>org.hibernate.service.jdbc.connections.spi.ConnectionProvider</tt>
|
* <td>classname of <tt>org.hibernate.service.jdbc.connections.spi.ConnectionProvider</tt>
|
||||||
* subclass (if not specified hueristics are used)</td>
|
* subclass (if not specified hueristics are used)</td>
|
||||||
|
|
|
@ -55,7 +55,7 @@ public abstract class ExternalSessionFactoryConfig {
|
||||||
private String querySubstitutions;
|
private String querySubstitutions;
|
||||||
private String showSqlEnabled;
|
private String showSqlEnabled;
|
||||||
private String commentsEnabled;
|
private String commentsEnabled;
|
||||||
private String cacheProviderClass;
|
private String cacheRegionFactory;
|
||||||
private String cacheProviderConfig;
|
private String cacheProviderConfig;
|
||||||
private String cacheRegionPrefix;
|
private String cacheRegionPrefix;
|
||||||
private String secondLevelCacheEnabled;
|
private String secondLevelCacheEnabled;
|
||||||
|
@ -209,12 +209,12 @@ public abstract class ExternalSessionFactoryConfig {
|
||||||
this.secondLevelCacheEnabled = secondLevelCacheEnabled;
|
this.secondLevelCacheEnabled = secondLevelCacheEnabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
public final String getCacheProviderClass() {
|
public final String getCacheRegionFactory() {
|
||||||
return cacheProviderClass;
|
return cacheRegionFactory;
|
||||||
}
|
}
|
||||||
|
|
||||||
public final void setCacheProviderClass(String cacheProviderClass) {
|
public final void setCacheRegionFactory(String cacheRegionFactory) {
|
||||||
this.cacheProviderClass = cacheProviderClass;
|
this.cacheRegionFactory = cacheRegionFactory;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getCacheProviderConfig() {
|
public String getCacheProviderConfig() {
|
||||||
|
@ -287,7 +287,7 @@ public abstract class ExternalSessionFactoryConfig {
|
||||||
setUnlessNull( props, Environment.QUERY_SUBSTITUTIONS, querySubstitutions );
|
setUnlessNull( props, Environment.QUERY_SUBSTITUTIONS, querySubstitutions );
|
||||||
setUnlessNull( props, Environment.SHOW_SQL, showSqlEnabled );
|
setUnlessNull( props, Environment.SHOW_SQL, showSqlEnabled );
|
||||||
setUnlessNull( props, Environment.USE_SQL_COMMENTS, commentsEnabled );
|
setUnlessNull( props, Environment.USE_SQL_COMMENTS, commentsEnabled );
|
||||||
setUnlessNull( props, Environment.CACHE_PROVIDER, cacheProviderClass );
|
setUnlessNull( props, Environment.CACHE_REGION_FACTORY, cacheRegionFactory );
|
||||||
setUnlessNull( props, Environment.CACHE_PROVIDER_CONFIG, cacheProviderConfig );
|
setUnlessNull( props, Environment.CACHE_PROVIDER_CONFIG, cacheProviderConfig );
|
||||||
setUnlessNull( props, Environment.CACHE_REGION_PREFIX, cacheRegionPrefix );
|
setUnlessNull( props, Environment.CACHE_REGION_PREFIX, cacheRegionPrefix );
|
||||||
setUnlessNull( props, Environment.USE_MINIMAL_PUTS, minimalPutsEnabled );
|
setUnlessNull( props, Environment.USE_MINIMAL_PUTS, minimalPutsEnabled );
|
||||||
|
|
|
@ -34,9 +34,9 @@ import org.hibernate.EntityMode;
|
||||||
import org.hibernate.HibernateException;
|
import org.hibernate.HibernateException;
|
||||||
import org.hibernate.MultiTenancyStrategy;
|
import org.hibernate.MultiTenancyStrategy;
|
||||||
import org.hibernate.cache.internal.NoCachingRegionFactory;
|
import org.hibernate.cache.internal.NoCachingRegionFactory;
|
||||||
|
import org.hibernate.cache.internal.StandardQueryCacheFactory;
|
||||||
import org.hibernate.cache.spi.QueryCacheFactory;
|
import org.hibernate.cache.spi.QueryCacheFactory;
|
||||||
import org.hibernate.cache.spi.RegionFactory;
|
import org.hibernate.cache.spi.RegionFactory;
|
||||||
import org.hibernate.cache.internal.bridge.RegionFactoryCacheProviderBridge;
|
|
||||||
import org.hibernate.engine.jdbc.spi.ExtractedDatabaseMetaData;
|
import org.hibernate.engine.jdbc.spi.ExtractedDatabaseMetaData;
|
||||||
import org.hibernate.engine.jdbc.spi.JdbcServices;
|
import org.hibernate.engine.jdbc.spi.JdbcServices;
|
||||||
import org.hibernate.engine.transaction.spi.TransactionFactory;
|
import org.hibernate.engine.transaction.spi.TransactionFactory;
|
||||||
|
@ -305,7 +305,7 @@ public class SettingsFactory implements Serializable {
|
||||||
|
|
||||||
protected QueryCacheFactory createQueryCacheFactory(Properties properties, ServiceRegistry serviceRegistry) {
|
protected QueryCacheFactory createQueryCacheFactory(Properties properties, ServiceRegistry serviceRegistry) {
|
||||||
String queryCacheFactoryClassName = ConfigurationHelper.getString(
|
String queryCacheFactoryClassName = ConfigurationHelper.getString(
|
||||||
Environment.QUERY_CACHE_FACTORY, properties, "org.hibernate.cache.internal.StandardQueryCacheFactory"
|
Environment.QUERY_CACHE_FACTORY, properties, StandardQueryCacheFactory.class.getName()
|
||||||
);
|
);
|
||||||
LOG.debugf( "Query cache factory: %s", queryCacheFactoryClassName );
|
LOG.debugf( "Query cache factory: %s", queryCacheFactoryClassName );
|
||||||
try {
|
try {
|
||||||
|
@ -318,18 +318,11 @@ public class SettingsFactory implements Serializable {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static RegionFactory createRegionFactory(Properties properties, boolean cachingEnabled, ServiceRegistry serviceRegistry) {
|
private static RegionFactory createRegionFactory(Properties properties, boolean cachingEnabled, ServiceRegistry serviceRegistry) {
|
||||||
String regionFactoryClassName = ConfigurationHelper.getString(
|
String regionFactoryClassName = ConfigurationHelper.getString(
|
||||||
Environment.CACHE_REGION_FACTORY, properties, null
|
Environment.CACHE_REGION_FACTORY, properties, null
|
||||||
);
|
);
|
||||||
if ( regionFactoryClassName == null && cachingEnabled ) {
|
if ( regionFactoryClassName == null || !cachingEnabled) {
|
||||||
String providerClassName = ConfigurationHelper.getString( Environment.CACHE_PROVIDER, properties, null );
|
|
||||||
if ( providerClassName != null ) {
|
|
||||||
// legacy behavior, apply the bridge...
|
|
||||||
regionFactoryClassName = RegionFactoryCacheProviderBridge.class.getName();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if ( regionFactoryClassName == null ) {
|
|
||||||
regionFactoryClassName = DEF_CACHE_REG_FACTORY;
|
regionFactoryClassName = DEF_CACHE_REG_FACTORY;
|
||||||
}
|
}
|
||||||
LOG.debugf( "Cache region factory : %s", regionFactoryClassName );
|
LOG.debugf( "Cache region factory : %s", regionFactoryClassName );
|
||||||
|
@ -355,6 +348,36 @@ public class SettingsFactory implements Serializable {
|
||||||
throw new HibernateException( "could not instantiate RegionFactory [" + regionFactoryClassName + "]", e );
|
throw new HibernateException( "could not instantiate RegionFactory [" + regionFactoryClassName + "]", e );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
//todo remove this once we move to new metamodel
|
||||||
|
public static RegionFactory createRegionFactory(Properties properties, boolean cachingEnabled) {
|
||||||
|
// todo : REMOVE! THIS IS TOTALLY A TEMPORARY HACK FOR org.hibernate.cfg.AnnotationBinder which will be going away
|
||||||
|
String regionFactoryClassName = ConfigurationHelper.getString(
|
||||||
|
Environment.CACHE_REGION_FACTORY, properties, null
|
||||||
|
);
|
||||||
|
if ( regionFactoryClassName == null ) {
|
||||||
|
regionFactoryClassName = DEF_CACHE_REG_FACTORY;
|
||||||
|
}
|
||||||
|
LOG.debugf( "Cache region factory : %s", regionFactoryClassName );
|
||||||
|
try {
|
||||||
|
try {
|
||||||
|
return (RegionFactory) org.hibernate.internal.util.ReflectHelper.classForName( regionFactoryClassName )
|
||||||
|
.getConstructor( Properties.class )
|
||||||
|
.newInstance( properties );
|
||||||
|
}
|
||||||
|
catch ( NoSuchMethodException e ) {
|
||||||
|
// no constructor accepting Properties found, try no arg constructor
|
||||||
|
LOG.debugf(
|
||||||
|
"%s did not provide constructor accepting java.util.Properties; attempting no-arg constructor.",
|
||||||
|
regionFactoryClassName
|
||||||
|
);
|
||||||
|
return (RegionFactory) org.hibernate.internal.util.ReflectHelper.classForName( regionFactoryClassName )
|
||||||
|
.newInstance();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch ( Exception e ) {
|
||||||
|
throw new HibernateException( "could not instantiate RegionFactory [" + regionFactoryClassName + "]", e );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
protected QueryTranslatorFactory createQueryTranslatorFactory(Properties properties, ServiceRegistry serviceRegistry) {
|
protected QueryTranslatorFactory createQueryTranslatorFactory(Properties properties, ServiceRegistry serviceRegistry) {
|
||||||
String className = ConfigurationHelper.getString(
|
String className = ConfigurationHelper.getString(
|
||||||
|
@ -370,41 +393,4 @@ public class SettingsFactory implements Serializable {
|
||||||
throw new HibernateException( "could not instantiate QueryTranslatorFactory: " + className, e );
|
throw new HibernateException( "could not instantiate QueryTranslatorFactory: " + className, e );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static RegionFactory createRegionFactory(Properties properties, boolean cachingEnabled) {
|
|
||||||
// todo : REMOVE! THIS IS TOTALLY A TEMPORARY HACK FOR org.hibernate.cfg.AnnotationBinder which will be going away
|
|
||||||
String regionFactoryClassName = ConfigurationHelper.getString(
|
|
||||||
Environment.CACHE_REGION_FACTORY, properties, null
|
|
||||||
);
|
|
||||||
if ( regionFactoryClassName == null && cachingEnabled ) {
|
|
||||||
String providerClassName = ConfigurationHelper.getString( Environment.CACHE_PROVIDER, properties, null );
|
|
||||||
if ( providerClassName != null ) {
|
|
||||||
// legacy behavior, apply the bridge...
|
|
||||||
regionFactoryClassName = RegionFactoryCacheProviderBridge.class.getName();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if ( regionFactoryClassName == null ) {
|
|
||||||
regionFactoryClassName = DEF_CACHE_REG_FACTORY;
|
|
||||||
}
|
|
||||||
LOG.debugf( "Cache region factory : %s", regionFactoryClassName );
|
|
||||||
try {
|
|
||||||
try {
|
|
||||||
return (RegionFactory) org.hibernate.internal.util.ReflectHelper.classForName( regionFactoryClassName )
|
|
||||||
.getConstructor( Properties.class )
|
|
||||||
.newInstance( properties );
|
|
||||||
}
|
|
||||||
catch ( NoSuchMethodException e ) {
|
|
||||||
// no constructor accepting Properties found, try no arg constructor
|
|
||||||
LOG.debugf(
|
|
||||||
"%s did not provide constructor accepting java.util.Properties; attempting no-arg constructor.",
|
|
||||||
regionFactoryClassName
|
|
||||||
);
|
|
||||||
return (RegionFactory) org.hibernate.internal.util.ReflectHelper.classForName( regionFactoryClassName )
|
|
||||||
.newInstance();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch ( Exception e ) {
|
|
||||||
throw new HibernateException( "could not instantiate RegionFactory [" + regionFactoryClassName + "]", e );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -222,11 +222,11 @@ public interface HibernateServiceMBean {
|
||||||
/**
|
/**
|
||||||
* Get the second-level cache provider class name
|
* Get the second-level cache provider class name
|
||||||
*/
|
*/
|
||||||
public String getCacheProviderClass();
|
public String getCacheRegionFactory();
|
||||||
/**
|
/**
|
||||||
* Set the second-level cache provider class name
|
* Set the second-level cache provider class name
|
||||||
*/
|
*/
|
||||||
public void setCacheProviderClass(String providerClassName);
|
public void setCacheRegionFactory(String cacheRegionFactory);
|
||||||
/**
|
/**
|
||||||
* For cache providers which support this setting, get the
|
* For cache providers which support this setting, get the
|
||||||
* provider's specific configuration resource.
|
* provider's specific configuration resource.
|
||||||
|
|
|
@ -1,159 +0,0 @@
|
||||||
/*
|
|
||||||
* Hibernate, Relational Persistence for Idiomatic Java
|
|
||||||
*
|
|
||||||
* Copyright (c) 2007-2011, Red Hat Inc. or third-party contributors as
|
|
||||||
* indicated by the @author tags or express copyright attribution
|
|
||||||
* statements applied by the authors. All third-party contributions are
|
|
||||||
* distributed under license by Red Hat Inc.
|
|
||||||
*
|
|
||||||
* This copyrighted material is made available to anyone wishing to use, modify,
|
|
||||||
* copy, or redistribute it subject to the terms and conditions of the GNU
|
|
||||||
* Lesser General Public License, as published by the Free Software Foundation.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
|
||||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
|
||||||
* for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Lesser General Public License
|
|
||||||
* along with this distribution; if not, write to:
|
|
||||||
* Free Software Foundation, Inc.
|
|
||||||
* 51 Franklin Street, Fifth Floor
|
|
||||||
* Boston, MA 02110-1301 USA
|
|
||||||
*/
|
|
||||||
package org.hibernate.test.legacy;
|
|
||||||
|
|
||||||
import org.hibernate.cache.spi.Cache;
|
|
||||||
import org.hibernate.cache.spi.CacheConcurrencyStrategy;
|
|
||||||
import org.hibernate.cache.spi.CacheProvider;
|
|
||||||
import org.hibernate.cache.internal.HashtableCacheProvider;
|
|
||||||
import org.hibernate.cache.spi.ReadWriteCache;
|
|
||||||
import org.hibernate.cache.spi.access.SoftLock;
|
|
||||||
|
|
||||||
import org.junit.Test;
|
|
||||||
|
|
||||||
import org.hibernate.testing.junit4.BaseUnitTestCase;
|
|
||||||
|
|
||||||
import static org.junit.Assert.assertTrue;
|
|
||||||
|
|
||||||
public class CacheTest extends BaseUnitTestCase {
|
|
||||||
@Test
|
|
||||||
public void testCaches() throws Exception {
|
|
||||||
doTestCache( new HashtableCacheProvider() );
|
|
||||||
}
|
|
||||||
|
|
||||||
public void doTestCache(CacheProvider cacheProvider) throws Exception {
|
|
||||||
|
|
||||||
Cache cache = cacheProvider.buildCache( String.class.getName(), System.getProperties() );
|
|
||||||
|
|
||||||
long longBefore = cache.nextTimestamp();
|
|
||||||
|
|
||||||
Thread.sleep( 15 );
|
|
||||||
|
|
||||||
long before = cache.nextTimestamp();
|
|
||||||
|
|
||||||
Thread.sleep( 15 );
|
|
||||||
|
|
||||||
//cache.setTimeout(1000);
|
|
||||||
CacheConcurrencyStrategy ccs = new ReadWriteCache();
|
|
||||||
ccs.setCache( cache );
|
|
||||||
|
|
||||||
// cache something
|
|
||||||
|
|
||||||
assertTrue( ccs.put( "foo", "foo", before, null, null, false ) );
|
|
||||||
|
|
||||||
Thread.sleep( 15 );
|
|
||||||
|
|
||||||
long after = cache.nextTimestamp();
|
|
||||||
|
|
||||||
assertTrue( ccs.get( "foo", longBefore ) == null );
|
|
||||||
assertTrue( ccs.get( "foo", after ).equals( "foo" ) );
|
|
||||||
|
|
||||||
assertTrue( !ccs.put( "foo", "foo", before, null, null, false ) );
|
|
||||||
|
|
||||||
// update it:
|
|
||||||
|
|
||||||
SoftLock lock = ccs.lock( "foo", null );
|
|
||||||
|
|
||||||
assertTrue( ccs.get( "foo", after ) == null );
|
|
||||||
assertTrue( ccs.get( "foo", longBefore ) == null );
|
|
||||||
|
|
||||||
assertTrue( !ccs.put( "foo", "foo", before, null, null, false ) );
|
|
||||||
|
|
||||||
Thread.sleep( 15 );
|
|
||||||
|
|
||||||
long whileLocked = cache.nextTimestamp();
|
|
||||||
|
|
||||||
assertTrue( !ccs.put( "foo", "foo", whileLocked, null, null, false ) );
|
|
||||||
|
|
||||||
Thread.sleep( 15 );
|
|
||||||
|
|
||||||
ccs.release( "foo", lock );
|
|
||||||
|
|
||||||
assertTrue( ccs.get( "foo", after ) == null );
|
|
||||||
assertTrue( ccs.get( "foo", longBefore ) == null );
|
|
||||||
|
|
||||||
assertTrue( !ccs.put( "foo", "bar", whileLocked, null, null, false ) );
|
|
||||||
assertTrue( !ccs.put( "foo", "bar", after, null, null, false ) );
|
|
||||||
|
|
||||||
Thread.sleep( 15 );
|
|
||||||
|
|
||||||
long longAfter = cache.nextTimestamp();
|
|
||||||
|
|
||||||
assertTrue( ccs.put( "foo", "baz", longAfter, null, null, false ) );
|
|
||||||
|
|
||||||
assertTrue( ccs.get( "foo", after ) == null );
|
|
||||||
assertTrue( ccs.get( "foo", whileLocked ) == null );
|
|
||||||
|
|
||||||
Thread.sleep( 15 );
|
|
||||||
|
|
||||||
long longLongAfter = cache.nextTimestamp();
|
|
||||||
|
|
||||||
assertTrue( ccs.get( "foo", longLongAfter ).equals( "baz" ) );
|
|
||||||
|
|
||||||
// update it again, with multiple locks:
|
|
||||||
|
|
||||||
SoftLock lock1 = ccs.lock( "foo", null );
|
|
||||||
SoftLock lock2 = ccs.lock( "foo", null );
|
|
||||||
|
|
||||||
assertTrue( ccs.get( "foo", longLongAfter ) == null );
|
|
||||||
|
|
||||||
Thread.sleep( 15 );
|
|
||||||
|
|
||||||
whileLocked = cache.nextTimestamp();
|
|
||||||
|
|
||||||
assertTrue( !ccs.put( "foo", "foo", whileLocked, null, null, false ) );
|
|
||||||
|
|
||||||
Thread.sleep( 15 );
|
|
||||||
|
|
||||||
ccs.release( "foo", lock2 );
|
|
||||||
|
|
||||||
Thread.sleep( 15 );
|
|
||||||
|
|
||||||
long betweenReleases = cache.nextTimestamp();
|
|
||||||
|
|
||||||
assertTrue( !ccs.put( "foo", "bar", betweenReleases, null, null, false ) );
|
|
||||||
assertTrue( ccs.get( "foo", betweenReleases ) == null );
|
|
||||||
|
|
||||||
Thread.sleep( 15 );
|
|
||||||
|
|
||||||
ccs.release( "foo", lock1 );
|
|
||||||
|
|
||||||
assertTrue( !ccs.put( "foo", "bar", whileLocked, null, null, false ) );
|
|
||||||
|
|
||||||
Thread.sleep( 15 );
|
|
||||||
|
|
||||||
longAfter = cache.nextTimestamp();
|
|
||||||
|
|
||||||
assertTrue( ccs.put( "foo", "baz", longAfter, null, null, false ) );
|
|
||||||
assertTrue( ccs.get( "foo", whileLocked ) == null );
|
|
||||||
|
|
||||||
Thread.sleep( 15 );
|
|
||||||
|
|
||||||
longLongAfter = cache.nextTimestamp();
|
|
||||||
|
|
||||||
assertTrue( ccs.get( "foo", longLongAfter ).equals( "baz" ) );
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -29,7 +29,6 @@ import java.sql.SQLException;
|
||||||
import org.hibernate.HibernateException;
|
import org.hibernate.HibernateException;
|
||||||
import org.hibernate.MultiTenancyStrategy;
|
import org.hibernate.MultiTenancyStrategy;
|
||||||
import org.hibernate.Session;
|
import org.hibernate.Session;
|
||||||
import org.hibernate.cache.internal.HashtableCacheProvider;
|
|
||||||
import org.hibernate.cfg.Configuration;
|
import org.hibernate.cfg.Configuration;
|
||||||
import org.hibernate.cfg.Environment;
|
import org.hibernate.cfg.Environment;
|
||||||
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||||
|
@ -40,6 +39,7 @@ import org.hibernate.service.jdbc.connections.spi.AbstractMultiTenantConnectionP
|
||||||
import org.hibernate.service.jdbc.connections.spi.ConnectionProvider;
|
import org.hibernate.service.jdbc.connections.spi.ConnectionProvider;
|
||||||
import org.hibernate.service.jdbc.connections.spi.MultiTenantConnectionProvider;
|
import org.hibernate.service.jdbc.connections.spi.MultiTenantConnectionProvider;
|
||||||
import org.hibernate.service.spi.ServiceRegistryImplementor;
|
import org.hibernate.service.spi.ServiceRegistryImplementor;
|
||||||
|
import org.hibernate.testing.cache.CachingRegionFactory;
|
||||||
import org.hibernate.tool.hbm2ddl.ConnectionHelper;
|
import org.hibernate.tool.hbm2ddl.ConnectionHelper;
|
||||||
import org.hibernate.tool.hbm2ddl.SchemaExport;
|
import org.hibernate.tool.hbm2ddl.SchemaExport;
|
||||||
|
|
||||||
|
@ -86,7 +86,7 @@ public class SchemaBasedMultiTenancyTest extends BaseUnitTestCase {
|
||||||
|
|
||||||
Configuration cfg = new Configuration();
|
Configuration cfg = new Configuration();
|
||||||
cfg.getProperties().put( Environment.MULTI_TENANT, MultiTenancyStrategy.DATABASE );
|
cfg.getProperties().put( Environment.MULTI_TENANT, MultiTenancyStrategy.DATABASE );
|
||||||
cfg.setProperty( Environment.CACHE_PROVIDER, HashtableCacheProvider.class.getName() );
|
cfg.setProperty( Environment.CACHE_REGION_FACTORY, CachingRegionFactory.class.getName() );
|
||||||
cfg.setProperty( Environment.GENERATE_STATISTICS, "true" );
|
cfg.setProperty( Environment.GENERATE_STATISTICS, "true" );
|
||||||
cfg.addAnnotatedClass( Customer.class );
|
cfg.addAnnotatedClass( Customer.class );
|
||||||
|
|
||||||
|
|
|
@ -33,4 +33,4 @@ hibernate.show_sql true
|
||||||
hibernate.max_fetch_depth 5
|
hibernate.max_fetch_depth 5
|
||||||
|
|
||||||
hibernate.cache.region_prefix hibernate.test
|
hibernate.cache.region_prefix hibernate.test
|
||||||
hibernate.cache.provider_class org.hibernate.cache.internal.HashtableCacheProvider
|
hibernate.cache.region.factory_class org.hibernate.testing.cache.CachingRegionFactory
|
||||||
|
|
|
@ -7,4 +7,4 @@ log4j.appender.stdout.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n
|
||||||
log4j.rootLogger=info, stdout
|
log4j.rootLogger=info, stdout
|
||||||
|
|
||||||
log4j.logger.org.hibernate.tool.hbm2ddl=debug
|
log4j.logger.org.hibernate.tool.hbm2ddl=debug
|
||||||
|
log4j.logger.org.hibernate.testing.cache=debug
|
||||||
|
|
|
@ -1,274 +0,0 @@
|
||||||
/*
|
|
||||||
* Hibernate, Relational Persistence for Idiomatic Java
|
|
||||||
*
|
|
||||||
* Copyright (c) 2007, Red Hat Middleware LLC or third-party contributors as
|
|
||||||
* indicated by the @author tags or express copyright attribution
|
|
||||||
* statements applied by the authors. All third-party contributions are
|
|
||||||
* distributed under license by Red Hat Middleware LLC.
|
|
||||||
*
|
|
||||||
* This copyrighted material is made available to anyone wishing to use, modify,
|
|
||||||
* copy, or redistribute it subject to the terms and conditions of the GNU
|
|
||||||
* Lesser General Public License, as published by the Free Software Foundation.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
|
||||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
|
||||||
* for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Lesser General Public License
|
|
||||||
* along with this distribution; if not, write to:
|
|
||||||
* Free Software Foundation, Inc.
|
|
||||||
* 51 Franklin Street, Fifth Floor
|
|
||||||
* Boston, MA 02110-1301 USA
|
|
||||||
*/
|
|
||||||
package org.hibernate.cache.internal;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Iterator;
|
|
||||||
import java.util.Map;
|
|
||||||
import net.sf.ehcache.CacheManager;
|
|
||||||
import net.sf.ehcache.Element;
|
|
||||||
import org.jboss.logging.Logger;
|
|
||||||
|
|
||||||
import org.hibernate.cache.spi.Cache;
|
|
||||||
import org.hibernate.cache.CacheException;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* EHCache plugin for Hibernate
|
|
||||||
* <p/>
|
|
||||||
* EHCache uses a {@link net.sf.ehcache.store.MemoryStore} and a
|
|
||||||
* {@link net.sf.ehcache.store.DiskStore}.
|
|
||||||
* The {@link net.sf.ehcache.store.DiskStore} requires that both keys and values be {@link java.io.Serializable}.
|
|
||||||
* However the MemoryStore does not and in ehcache-1.2 nonSerializable Objects are permitted. They are discarded
|
|
||||||
* if an attempt it made to overflow them to Disk or to replicate them to remote cache peers.
|
|
||||||
*
|
|
||||||
* @author Greg Luck
|
|
||||||
* @author Emmanuel Bernard
|
|
||||||
*/
|
|
||||||
@Deprecated
|
|
||||||
public class EhCache implements Cache {
|
|
||||||
|
|
||||||
private static final EhCacheMessageLogger LOG = Logger.getMessageLogger(EhCacheMessageLogger.class, EhCache.class.getName());
|
|
||||||
|
|
||||||
private static final int SIXTY_THOUSAND_MS = 60000;
|
|
||||||
|
|
||||||
private net.sf.ehcache.Ehcache cache;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates a new Hibernate pluggable cache based on a cache name.
|
|
||||||
* <p/>
|
|
||||||
*
|
|
||||||
* @param cache The underlying EhCache instance to use.
|
|
||||||
*/
|
|
||||||
public EhCache(net.sf.ehcache.Ehcache cache) {
|
|
||||||
this.cache = cache;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets a value of an element which matches the given key.
|
|
||||||
*
|
|
||||||
* @param key the key of the element to return.
|
|
||||||
* @return The value placed into the cache with an earlier put, or null if not found or expired
|
|
||||||
* @throws org.hibernate.cache.CacheException
|
|
||||||
*/
|
|
||||||
public Object get(Object key) throws CacheException {
|
|
||||||
try {
|
|
||||||
LOG.debugf("Key: %s", key);
|
|
||||||
if (key == null) return null;
|
|
||||||
Element element = cache.get(key);
|
|
||||||
if (element == null) {
|
|
||||||
LOG.debugf("Element for %s is null", key);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return element.getObjectValue();
|
|
||||||
}
|
|
||||||
catch (net.sf.ehcache.CacheException e) {
|
|
||||||
throw new CacheException( e );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public Object read(Object key) throws CacheException {
|
|
||||||
return get( key );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Puts an object into the cache.
|
|
||||||
*
|
|
||||||
* @param key a key
|
|
||||||
* @param value a value
|
|
||||||
* @throws CacheException if the {@link CacheManager}
|
|
||||||
* is shutdown or another {@link Exception} occurs.
|
|
||||||
*/
|
|
||||||
public void update(Object key, Object value) throws CacheException {
|
|
||||||
put( key, value );
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Puts an object into the cache.
|
|
||||||
*
|
|
||||||
* @param key a key
|
|
||||||
* @param value a value
|
|
||||||
* @throws CacheException if the {@link CacheManager}
|
|
||||||
* is shutdown or another {@link Exception} occurs.
|
|
||||||
*/
|
|
||||||
public void put(Object key, Object value) throws CacheException {
|
|
||||||
try {
|
|
||||||
Element element = new Element( key, value );
|
|
||||||
cache.put( element );
|
|
||||||
}
|
|
||||||
catch (IllegalArgumentException e) {
|
|
||||||
throw new CacheException( e );
|
|
||||||
}
|
|
||||||
catch (IllegalStateException e) {
|
|
||||||
throw new CacheException( e );
|
|
||||||
}
|
|
||||||
catch (net.sf.ehcache.CacheException e) {
|
|
||||||
throw new CacheException( e );
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Removes the element which matches the key.
|
|
||||||
* <p/>
|
|
||||||
* If no element matches, nothing is removed and no Exception is thrown.
|
|
||||||
*
|
|
||||||
* @param key the key of the element to remove
|
|
||||||
* @throws CacheException
|
|
||||||
*/
|
|
||||||
public void remove(Object key) throws CacheException {
|
|
||||||
try {
|
|
||||||
cache.remove( key );
|
|
||||||
}
|
|
||||||
catch (ClassCastException e) {
|
|
||||||
throw new CacheException( e );
|
|
||||||
}
|
|
||||||
catch (IllegalStateException e) {
|
|
||||||
throw new CacheException( e );
|
|
||||||
}
|
|
||||||
catch (net.sf.ehcache.CacheException e) {
|
|
||||||
throw new CacheException( e );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Remove all elements in the cache, but leave the cache
|
|
||||||
* in a useable state.
|
|
||||||
*
|
|
||||||
* @throws CacheException
|
|
||||||
*/
|
|
||||||
public void clear() throws CacheException {
|
|
||||||
try {
|
|
||||||
cache.removeAll();
|
|
||||||
}
|
|
||||||
catch (IllegalStateException e) {
|
|
||||||
throw new CacheException( e );
|
|
||||||
}
|
|
||||||
catch (net.sf.ehcache.CacheException e) {
|
|
||||||
throw new CacheException( e );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Remove the cache and make it unuseable.
|
|
||||||
*
|
|
||||||
* @throws CacheException
|
|
||||||
*/
|
|
||||||
public void destroy() throws CacheException {
|
|
||||||
try {
|
|
||||||
cache.getCacheManager().removeCache( cache.getName() );
|
|
||||||
}
|
|
||||||
catch (IllegalStateException e) {
|
|
||||||
throw new CacheException( e );
|
|
||||||
}
|
|
||||||
catch (net.sf.ehcache.CacheException e) {
|
|
||||||
throw new CacheException( e );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Calls to this method should perform there own synchronization.
|
|
||||||
* It is provided for distributed caches. Because EHCache is not distributed
|
|
||||||
* this method does nothing.
|
|
||||||
*/
|
|
||||||
public void lock(Object key) throws CacheException {
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Calls to this method should perform there own synchronization.
|
|
||||||
* It is provided for distributed caches. Because EHCache is not distributed
|
|
||||||
* this method does nothing.
|
|
||||||
*/
|
|
||||||
public void unlock(Object key) throws CacheException {
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the next timestamp;
|
|
||||||
*/
|
|
||||||
public long nextTimestamp() {
|
|
||||||
return Timestamper.next();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the lock timeout for this cache.
|
|
||||||
*/
|
|
||||||
public int getTimeout() {
|
|
||||||
// 60 second lock timeout
|
|
||||||
return Timestamper.ONE_MS * SIXTY_THOUSAND_MS;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getRegionName() {
|
|
||||||
return cache.getName();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Warning: This method can be very expensive to run. Allow approximately 1 second
|
|
||||||
* per 1MB of entries. Running this method could create liveness problems
|
|
||||||
* because the object lock is held for a long period
|
|
||||||
* <p/>
|
|
||||||
*
|
|
||||||
* @return the approximate size of memory ehcache is using for the MemoryStore for this cache
|
|
||||||
*/
|
|
||||||
public long getSizeInMemory() {
|
|
||||||
try {
|
|
||||||
return cache.calculateInMemorySize();
|
|
||||||
}
|
|
||||||
catch (Throwable t) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public long getElementCountInMemory() {
|
|
||||||
try {
|
|
||||||
return cache.getMemoryStoreSize();
|
|
||||||
}
|
|
||||||
catch (net.sf.ehcache.CacheException ce) {
|
|
||||||
throw new CacheException( ce );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public long getElementCountOnDisk() {
|
|
||||||
return cache.getDiskStoreSize();
|
|
||||||
}
|
|
||||||
|
|
||||||
public Map toMap() {
|
|
||||||
try {
|
|
||||||
Map result = new HashMap();
|
|
||||||
Iterator iter = cache.getKeys().iterator();
|
|
||||||
while ( iter.hasNext() ) {
|
|
||||||
Object key = iter.next();
|
|
||||||
result.put( key, cache.get( key ).getObjectValue() );
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
catch (Exception e) {
|
|
||||||
throw new CacheException( e );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return "EHCache(" + getRegionName() + ')';
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,171 +0,0 @@
|
||||||
/*
|
|
||||||
* Hibernate, Relational Persistence for Idiomatic Java
|
|
||||||
*
|
|
||||||
* Copyright (c) 2007-2011, Red Hat Inc. or third-party contributors as
|
|
||||||
* indicated by the @author tags or express copyright attribution
|
|
||||||
* statements applied by the authors. All third-party contributions are
|
|
||||||
* distributed under license by Red Hat Inc.
|
|
||||||
*
|
|
||||||
* This copyrighted material is made available to anyone wishing to use, modify,
|
|
||||||
* copy, or redistribute it subject to the terms and conditions of the GNU
|
|
||||||
* Lesser General Public License, as published by the Free Software Foundation.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
|
||||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
|
||||||
* for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Lesser General Public License
|
|
||||||
* along with this distribution; if not, write to:
|
|
||||||
* Free Software Foundation, Inc.
|
|
||||||
* 51 Franklin Street, Fifth Floor
|
|
||||||
* Boston, MA 02110-1301 USA
|
|
||||||
*/
|
|
||||||
package org.hibernate.cache.internal;
|
|
||||||
|
|
||||||
import java.net.URL;
|
|
||||||
import java.util.Properties;
|
|
||||||
import net.sf.ehcache.CacheManager;
|
|
||||||
|
|
||||||
import org.hibernate.cache.spi.Cache;
|
|
||||||
import org.hibernate.cache.CacheException;
|
|
||||||
import org.hibernate.cache.spi.CacheProvider;
|
|
||||||
import org.hibernate.cfg.Environment;
|
|
||||||
import org.hibernate.internal.util.ConfigHelper;
|
|
||||||
import org.hibernate.internal.util.StringHelper;
|
|
||||||
import org.jboss.logging.Logger;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Cache Provider plugin for Hibernate
|
|
||||||
*
|
|
||||||
* Use <code>hibernate.cache.provider_class=org.hibernate.cache.internal.EhCacheProvider</code>
|
|
||||||
* in Hibernate 3.x or later
|
|
||||||
*
|
|
||||||
* Taken from EhCache 0.9 distribution
|
|
||||||
* @author Greg Luck
|
|
||||||
* @author Emmanuel Bernard
|
|
||||||
*/
|
|
||||||
/**
|
|
||||||
* Cache Provider plugin for ehcache-1.2. New in this provider are ehcache support for multiple
|
|
||||||
* Hibernate session factories, each with its own ehcache configuration, and non Serializable keys and values.
|
|
||||||
* Ehcache-1.2 also has many other features such as cluster support and listeners, which can be used seamlessly simply
|
|
||||||
* by configurion in ehcache.xml.
|
|
||||||
* <p/>
|
|
||||||
* Use <code>hibernate.cache.provider_class=org.hibernate.cache.internal.EhCacheProvider</code> in the Hibernate configuration
|
|
||||||
* to enable this provider for Hibernate's second level cache.
|
|
||||||
* <p/>
|
|
||||||
* When configuring multiple ehcache CacheManagers, as you would where you have multiple Hibernate Configurations and
|
|
||||||
* multiple SessionFactories, specify in each Hibernate configuration the ehcache configuration using
|
|
||||||
* the property <code>hibernate.cache.provider_configuration_file_resource_path</code> An example to set an ehcache configuration
|
|
||||||
* called ehcache-2.xml would be <code>hibernate.cache.provider_configuration_file_resource_path=/ehcache-2.xml</code>. If the leading
|
|
||||||
* slash is not there one will be added. The configuration file will be looked for in the root of the classpath.
|
|
||||||
* <p/>
|
|
||||||
* Updated for ehcache-1.2. Note this provider requires ehcache-1.2.jar. Make sure ehcache-1.1.jar or earlier
|
|
||||||
* is not in the classpath or it will not work.
|
|
||||||
* <p/>
|
|
||||||
* See http://ehcache.sf.net for documentation on ehcache
|
|
||||||
* <p/>
|
|
||||||
*
|
|
||||||
* @author Greg Luck
|
|
||||||
* @author Emmanuel Bernard
|
|
||||||
*/
|
|
||||||
@Deprecated
|
|
||||||
public class EhCacheProvider implements CacheProvider {
|
|
||||||
|
|
||||||
private static final EhCacheMessageLogger LOG = Logger.getMessageLogger(EhCacheMessageLogger.class, EhCacheProvider.class.getName());
|
|
||||||
|
|
||||||
private CacheManager manager;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Builds a Cache.
|
|
||||||
* <p>
|
|
||||||
* Even though this method provides properties, they are not used.
|
|
||||||
* Properties for EHCache are specified in the ehcache.xml file.
|
|
||||||
* Configuration will be read from ehcache.xml for a cache declaration
|
|
||||||
* where the name attribute matches the name parameter in this builder.
|
|
||||||
*
|
|
||||||
* @param name the name of the cache. Must match a cache configured in ehcache.xml
|
|
||||||
* @param properties not used
|
|
||||||
* @return a newly built cache will be built and initialised
|
|
||||||
* @throws org.hibernate.cache.CacheException inter alia, if a cache of the same name already exists
|
|
||||||
*/
|
|
||||||
public Cache buildCache(String name, Properties properties) throws CacheException {
|
|
||||||
try {
|
|
||||||
net.sf.ehcache.Cache cache = manager.getCache(name);
|
|
||||||
if (cache == null) {
|
|
||||||
LOG.unableToFindConfiguration(name);
|
|
||||||
manager.addCache(name);
|
|
||||||
cache = manager.getCache(name);
|
|
||||||
LOG.debugf("Started EHCache region: %s", name);
|
|
||||||
}
|
|
||||||
return new EhCache(cache);
|
|
||||||
}
|
|
||||||
catch (net.sf.ehcache.CacheException e) {
|
|
||||||
throw new CacheException(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the next timestamp.
|
|
||||||
*/
|
|
||||||
public long nextTimestamp() {
|
|
||||||
return Timestamper.next();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Callback to perform any necessary initialization of the underlying cache implementation
|
|
||||||
* during SessionFactory construction.
|
|
||||||
*
|
|
||||||
* @param properties current configuration settings.
|
|
||||||
*/
|
|
||||||
public void start(Properties properties) throws CacheException {
|
|
||||||
if (manager != null) {
|
|
||||||
LOG.attemptToRestartAlreadyStartedEhCacheProvider();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
String configurationResourceName = null;
|
|
||||||
if (properties != null) {
|
|
||||||
configurationResourceName = (String) properties.get( Environment.CACHE_PROVIDER_CONFIG );
|
|
||||||
}
|
|
||||||
if ( StringHelper.isEmpty( configurationResourceName ) ) {
|
|
||||||
manager = new CacheManager();
|
|
||||||
} else {
|
|
||||||
URL url = loadResource(configurationResourceName);
|
|
||||||
manager = new CacheManager(url);
|
|
||||||
}
|
|
||||||
} catch (net.sf.ehcache.CacheException e) {
|
|
||||||
//yukky! Don't you have subclasses for that!
|
|
||||||
//TODO race conditions can happen here
|
|
||||||
if (e.getMessage().startsWith("Cannot parseConfiguration CacheManager. Attempt to create a new instance of " +
|
|
||||||
"CacheManager using the diskStorePath")) {
|
|
||||||
throw new CacheException("Attempt to restart an already started EhCacheProvider. Use sessionFactory.close() " +
|
|
||||||
" between repeated calls to buildSessionFactory. Consider using net.sf.ehcache.hibernate.SingletonEhCacheProvider."
|
|
||||||
, e );
|
|
||||||
}
|
|
||||||
throw e;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private URL loadResource(String configurationResourceName) {
|
|
||||||
URL url = ConfigHelper.locateConfig( configurationResourceName );
|
|
||||||
LOG.debugf("Creating EhCacheProvider from a specified resource: %s Resolved to URL: %s", configurationResourceName, url);
|
|
||||||
return url;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Callback to perform any necessary cleanup of the underlying cache implementation
|
|
||||||
* during SessionFactory.close().
|
|
||||||
*/
|
|
||||||
public void stop() {
|
|
||||||
if (manager != null) {
|
|
||||||
manager.shutdown();
|
|
||||||
manager = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isMinimalPutsEnabledByDefault() {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,185 +0,0 @@
|
||||||
/*
|
|
||||||
* Hibernate, Relational Persistence for Idiomatic Java
|
|
||||||
*
|
|
||||||
* Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
|
|
||||||
* indicated by the @author tags or express copyright attribution
|
|
||||||
* statements applied by the authors. All third-party contributions are
|
|
||||||
* distributed under license by Red Hat Middleware LLC.
|
|
||||||
*
|
|
||||||
* This copyrighted material is made available to anyone wishing to use, modify,
|
|
||||||
* copy, or redistribute it subject to the terms and conditions of the GNU
|
|
||||||
* Lesser General Public License, as published by the Free Software Foundation.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
|
||||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
|
||||||
* for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Lesser General Public License
|
|
||||||
* along with this distribution; if not, write to:
|
|
||||||
* Free Software Foundation, Inc.
|
|
||||||
* 51 Franklin Street, Fifth Floor
|
|
||||||
* Boston, MA 02110-1301 USA
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
package org.hibernate.cache.internal;
|
|
||||||
import java.net.URL;
|
|
||||||
import java.util.Properties;
|
|
||||||
import net.sf.ehcache.CacheManager;
|
|
||||||
import net.sf.ehcache.util.ClassLoaderUtil;
|
|
||||||
import org.jboss.logging.Logger;
|
|
||||||
import org.jboss.logging.Logger.Level;
|
|
||||||
|
|
||||||
import org.hibernate.cache.spi.Cache;
|
|
||||||
import org.hibernate.cache.CacheException;
|
|
||||||
import org.hibernate.cache.spi.CacheProvider;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Singleton cache Provider plugin for Hibernate 3.2 and ehcache-1.2. New in this provider is support for
|
|
||||||
* non Serializable keys and values. This provider works as a Singleton. No matter how many Hibernate Configurations
|
|
||||||
* you have, only one ehcache CacheManager is used. See EhCacheProvider for a non-singleton implementation.
|
|
||||||
* <p/>
|
|
||||||
* Ehcache-1.2 also has many other features such as cluster support and listeners, which can be used seamlessly simply
|
|
||||||
* by configurion in ehcache.xml.
|
|
||||||
* <p/>
|
|
||||||
* Use <code>hibernate.cache.provider_class=net.sf.ehcache.hibernate.SingletonEhCacheProvider</code> in the Hibernate configuration
|
|
||||||
* to enable this provider for Hibernate's second level cache.
|
|
||||||
* <p/>
|
|
||||||
* Updated for ehcache-1.2. Note this provider requires ehcache-1.2.jar. Make sure ehcache-1.1.jar or earlier
|
|
||||||
* is not in the classpath or it will not work.
|
|
||||||
* <p/>
|
|
||||||
* See http://ehcache.sf.net for documentation on ehcache
|
|
||||||
* <p/>
|
|
||||||
*
|
|
||||||
* @author Greg Luck
|
|
||||||
* @author Emmanuel Bernard
|
|
||||||
* @version $Id: SingletonEhCacheProvider.java 744 2008-08-16 20:10:49Z gregluck $
|
|
||||||
*/
|
|
||||||
@Deprecated
|
|
||||||
public final class SingletonEhCacheProvider implements CacheProvider {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The Hibernate system property specifying the location of the ehcache configuration file name.
|
|
||||||
* <p/
|
|
||||||
* If not set, ehcache.xml will be looked for in the root of the classpath.
|
|
||||||
* <p/>
|
|
||||||
* If set to say ehcache-1.xml, ehcache-1.xml will be looked for in the root of the classpath.
|
|
||||||
*/
|
|
||||||
public static final String NET_SF_EHCACHE_CONFIGURATION_RESOURCE_NAME = "net.sf.ehcache.configurationResourceName";
|
|
||||||
|
|
||||||
private static final EhCacheMessageLogger LOG = Logger.getMessageLogger(EhCacheMessageLogger.class, SingletonEhCacheProvider.class.getName());
|
|
||||||
|
|
||||||
/**
|
|
||||||
* To be backwardly compatible with a lot of Hibernate code out there, allow multiple starts and stops on the
|
|
||||||
* one singleton CacheManager. Keep a count of references to only stop on when only one reference is held.
|
|
||||||
*/
|
|
||||||
private static int referenceCount;
|
|
||||||
|
|
||||||
private CacheManager manager;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Builds a Cache.
|
|
||||||
* <p/>
|
|
||||||
* Even though this method provides properties, they are not used.
|
|
||||||
* Properties for EHCache are specified in the ehcache.xml file.
|
|
||||||
* Configuration will be read from ehcache.xml for a cache declaration
|
|
||||||
* where the name attribute matches the name parameter in this builder.
|
|
||||||
*
|
|
||||||
* @param name the name of the cache. Must match a cache configured in ehcache.xml
|
|
||||||
* @param properties not used
|
|
||||||
*
|
|
||||||
* @return a newly built cache will be built and initialised
|
|
||||||
*
|
|
||||||
* @throws org.hibernate.cache.CacheException
|
|
||||||
* inter alia, if a cache of the same name already exists
|
|
||||||
*/
|
|
||||||
public final Cache buildCache(String name, Properties properties) throws CacheException {
|
|
||||||
try {
|
|
||||||
net.sf.ehcache.Ehcache cache = manager.getEhcache( name );
|
|
||||||
if ( cache == null ) {
|
|
||||||
LOG.unableToFindEhCacheConfiguration(name);
|
|
||||||
manager.addCache( name );
|
|
||||||
cache = manager.getEhcache( name );
|
|
||||||
LOG.debugf("Started EHCache region: %s", name);
|
|
||||||
}
|
|
||||||
return new EhCache( cache );
|
|
||||||
}
|
|
||||||
catch ( net.sf.ehcache.CacheException e ) {
|
|
||||||
throw new CacheException( e );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the next timestamp.
|
|
||||||
*/
|
|
||||||
public final long nextTimestamp() {
|
|
||||||
return Timestamper.next();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Callback to perform any necessary initialization of the underlying cache implementation
|
|
||||||
* during SessionFactory construction.
|
|
||||||
* <p/>
|
|
||||||
*
|
|
||||||
* @param properties current configuration settings.
|
|
||||||
*/
|
|
||||||
public final void start(Properties properties) throws CacheException {
|
|
||||||
String configurationResourceName = null;
|
|
||||||
if ( properties != null ) {
|
|
||||||
configurationResourceName = ( String ) properties.get( NET_SF_EHCACHE_CONFIGURATION_RESOURCE_NAME );
|
|
||||||
}
|
|
||||||
if ( configurationResourceName == null || configurationResourceName.length() == 0 ) {
|
|
||||||
manager = CacheManager.create();
|
|
||||||
referenceCount++;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
if ( !configurationResourceName.startsWith( "/" ) ) {
|
|
||||||
configurationResourceName = "/" + configurationResourceName;
|
|
||||||
if (LOG.isDebugEnabled()) {
|
|
||||||
LOG.debugf("Prepending / to %s. It should be placed in the root of the classpath rather than in a package.",
|
|
||||||
configurationResourceName);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
URL url = loadResource( configurationResourceName );
|
|
||||||
manager = CacheManager.create( url );
|
|
||||||
referenceCount++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private URL loadResource(String configurationResourceName) {
|
|
||||||
ClassLoader standardClassloader = ClassLoaderUtil.getStandardClassLoader();
|
|
||||||
URL url = null;
|
|
||||||
if (standardClassloader != null) url = standardClassloader.getResource(configurationResourceName);
|
|
||||||
if (url == null) url = this.getClass().getResource(configurationResourceName);
|
|
||||||
if (LOG.isDebugEnabled()) LOG.debugf("Creating EhCacheProvider from a specified resource: %s Resolved to URL: %s",
|
|
||||||
configurationResourceName,
|
|
||||||
url);
|
|
||||||
if (url == null && LOG.isEnabled(Level.WARN)) LOG.unableToLoadConfiguration(configurationResourceName);
|
|
||||||
return url;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Callback to perform any necessary cleanup of the underlying cache implementation
|
|
||||||
* during SessionFactory.close().
|
|
||||||
*/
|
|
||||||
public void stop() {
|
|
||||||
if ( manager != null ) {
|
|
||||||
referenceCount--;
|
|
||||||
if ( referenceCount == 0 ) {
|
|
||||||
manager.shutdown();
|
|
||||||
}
|
|
||||||
manager = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Not sure what this is supposed to do.
|
|
||||||
*
|
|
||||||
* @return false to be safe
|
|
||||||
*/
|
|
||||||
public final boolean isMinimalPutsEnabledByDefault() {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,31 +1,31 @@
|
||||||
package org.hibernate.test.cache.ehcache;
|
package org.hibernate.test.cache.ehcache;
|
||||||
|
|
||||||
import org.hibernate.cache.spi.ReadWriteCache.Item;
|
|
||||||
import org.hibernate.cache.internal.EhCacheProvider;
|
|
||||||
import org.hibernate.cfg.Configuration;
|
import org.hibernate.cfg.Configuration;
|
||||||
import org.hibernate.cfg.Environment;
|
import org.hibernate.cfg.Environment;
|
||||||
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
|
import net.sf.ehcache.hibernate.EhCacheRegionFactory;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Alex Snaps
|
* @author Alex Snaps
|
||||||
*/
|
*/
|
||||||
public class EhCacheRegionTest extends EhCacheTest {
|
public class EhCacheRegionTest extends EhCacheTest {
|
||||||
@Override
|
@Override
|
||||||
protected void configCache(final Configuration cfg) {
|
protected void configCache(final Configuration cfg) {
|
||||||
cfg.setProperty( Environment.CACHE_PROVIDER, EhCacheProvider.class.getName() );
|
cfg.setProperty( Environment.CACHE_REGION_FACTORY, EhCacheRegionFactory.class.getName() );
|
||||||
cfg.setProperty( Environment.CACHE_PROVIDER_CONFIG, "ehcache.xml" );
|
cfg.setProperty( Environment.CACHE_PROVIDER_CONFIG, "ehcache.xml" );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Map getMapFromCacheEntry(final Object entry) {
|
protected Map getMapFromCacheEntry(final Object entry) {
|
||||||
final Map map;
|
final Map map;
|
||||||
if ( entry instanceof Item ) {
|
// if ( entry instanceof Item ) {
|
||||||
map = (Map) ( (Item) entry ).getValue();
|
// map = (Map) ( (Item) entry ).getValue();
|
||||||
}
|
// }
|
||||||
else {
|
// else {
|
||||||
map = (Map) entry;
|
map = (Map) entry;
|
||||||
}
|
// }
|
||||||
return map;
|
return map;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,8 +26,6 @@ package org.hibernate.test.cache.ehcache;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import org.hibernate.Session;
|
import org.hibernate.Session;
|
||||||
import org.hibernate.Transaction;
|
import org.hibernate.Transaction;
|
||||||
import org.hibernate.cache.internal.EhCacheProvider;
|
|
||||||
import org.hibernate.cache.spi.ReadWriteCache;
|
|
||||||
import org.hibernate.cfg.Configuration;
|
import org.hibernate.cfg.Configuration;
|
||||||
import org.hibernate.cfg.Environment;
|
import org.hibernate.cfg.Environment;
|
||||||
import org.hibernate.engine.transaction.internal.jdbc.JdbcTransactionFactory;
|
import org.hibernate.engine.transaction.internal.jdbc.JdbcTransactionFactory;
|
||||||
|
@ -184,10 +182,11 @@ public abstract class EhCacheTest extends BaseCoreFunctionalTestCase {
|
||||||
|
|
||||||
Object entry = slcs.getEntries().get( item.getId() );
|
Object entry = slcs.getEntries().get( item.getId() );
|
||||||
Long cachedVersionValue;
|
Long cachedVersionValue;
|
||||||
if ( entry instanceof ReadWriteCache.Lock ) {
|
// if ( entry instanceof ReadWriteCache.Lock ) {
|
||||||
//FIXME don't know what to test here
|
// //FIXME don't know what to test here
|
||||||
cachedVersionValue = Long.valueOf( ((ReadWriteCache.Lock) entry).getUnlockTimestamp() );
|
// cachedVersionValue = Long.valueOf( ((ReadWriteCache.Lock) entry).getUnlockTimestamp() );
|
||||||
} else if(entry.getClass().getName().equals("net.sf.ehcache.hibernate.strategy.AbstractReadWriteEhcacheAccessStrategy$Lock")) {
|
// } else
|
||||||
|
if(entry.getClass().getName().equals("net.sf.ehcache.hibernate.strategy.AbstractReadWriteEhcacheAccessStrategy$Lock")) {
|
||||||
//FIXME don't know what to test here
|
//FIXME don't know what to test here
|
||||||
} else {
|
} else {
|
||||||
cachedVersionValue = ( Long ) getMapFromCacheEntry(entry).get( "_version" );
|
cachedVersionValue = ( Long ) getMapFromCacheEntry(entry).get( "_version" );
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
<property name="hibernate.max_fetch_depth">3</property>
|
<property name="hibernate.max_fetch_depth">3</property>
|
||||||
<property name="hibernate.hbm2ddl.auto">create-drop</property>
|
<property name="hibernate.hbm2ddl.auto">create-drop</property>
|
||||||
<property name="hibernate.generate_statistics">true</property>
|
<property name="hibernate.generate_statistics">true</property>
|
||||||
<property name="hibernate.cache.provider_class">org.hibernate.cache.internal.HashtableCacheProvider</property>
|
<property name="hibernate.cache.region.factory_class">org.hibernate.testing.cache.CachingRegionFactory</property>
|
||||||
<mapping class="org.hibernate.ejb.test.Item"/>
|
<mapping class="org.hibernate.ejb.test.Item"/>
|
||||||
<mapping class="org.hibernate.ejb.test.Cat"/>
|
<mapping class="org.hibernate.ejb.test.Cat"/>
|
||||||
<mapping class="org.hibernate.ejb.test.Kitten"/>
|
<mapping class="org.hibernate.ejb.test.Kitten"/>
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
<property name="hibernate.connection.password" value="@jdbc.pass@"/>
|
<property name="hibernate.connection.password" value="@jdbc.pass@"/>
|
||||||
<property name="hibernate.connection.url" value="@jdbc.url@"/>
|
<property name="hibernate.connection.url" value="@jdbc.url@"/>
|
||||||
<property name="hibernate.hbm2ddl.auto" value="create-drop"/>
|
<property name="hibernate.hbm2ddl.auto" value="create-drop"/>
|
||||||
<property name="hibernate.cache.provider_class" value="org.hibernate.cache.internal.HashtableCacheProvider"/>
|
<property name="hibernate.cache.region.factory_class" value="org.hibernate.testing.cache.CachingRegionFactory" />
|
||||||
</properties>
|
</properties>
|
||||||
</persistence-unit>
|
</persistence-unit>
|
||||||
</persistence>
|
</persistence>
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
<property name="hibernate.connection.password" value="@jdbc.pass@"/>
|
<property name="hibernate.connection.password" value="@jdbc.pass@"/>
|
||||||
<property name="hibernate.connection.url" value="@jdbc.url@"/>
|
<property name="hibernate.connection.url" value="@jdbc.url@"/>
|
||||||
<property name="hibernate.hbm2ddl.auto" value="create-drop"/>
|
<property name="hibernate.hbm2ddl.auto" value="create-drop"/>
|
||||||
<property name="hibernate.cache.provider_class" value="org.hibernate.cache.internal.HashtableCacheProvider"/>
|
<property name="hibernate.cache.region.factory_class" value="org.hibernate.testing.cache.CachingRegionFactory" />
|
||||||
</properties>
|
</properties>
|
||||||
</persistence-unit>
|
</persistence-unit>
|
||||||
</persistence>
|
</persistence>
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
<property name="hibernate.connection.password" value="@jdbc.pass@"/>
|
<property name="hibernate.connection.password" value="@jdbc.pass@"/>
|
||||||
<property name="hibernate.connection.url" value="@jdbc.url@"/>
|
<property name="hibernate.connection.url" value="@jdbc.url@"/>
|
||||||
<property name="hibernate.hbm2ddl.auto" value="create-drop"/>
|
<property name="hibernate.hbm2ddl.auto" value="create-drop"/>
|
||||||
<property name="hibernate.cache.provider_class" value="org.hibernate.cache.internal.HashtableCacheProvider"/>
|
<property name="hibernate.cache.region.factory_class" value="org.hibernate.testing.cache.CachingRegionFactory" />
|
||||||
<property name="hibernate.archive.autodetection" value="class"/>
|
<property name="hibernate.archive.autodetection" value="class"/>
|
||||||
</properties>
|
</properties>
|
||||||
</persistence-unit>
|
</persistence-unit>
|
||||||
|
|
|
@ -26,7 +26,7 @@
|
||||||
<property name="hibernate.max_fetch_depth" value="3"/>
|
<property name="hibernate.max_fetch_depth" value="3"/>
|
||||||
<property name="hibernate.hbm2ddl.auto" value="create-drop"/>
|
<property name="hibernate.hbm2ddl.auto" value="create-drop"/>
|
||||||
<property name="hibernate.generate_statistics" value="true"/>
|
<property name="hibernate.generate_statistics" value="true"/>
|
||||||
<property name="hibernate.cache.provider_class" value="org.hibernate.cache.internal.HashtableCacheProvider"/>
|
<property name="hibernate.cache.region.factory_class" value="org.hibernate.testing.cache.CachingRegionFactory" />
|
||||||
<property name="hibernate.ejb.naming_strategy" value="org.hibernate.ejb.test.MyNamingStrategy"/>
|
<property name="hibernate.ejb.naming_strategy" value="org.hibernate.ejb.test.MyNamingStrategy"/>
|
||||||
<!-- test naming strategy and fall back to element content -->
|
<!-- test naming strategy and fall back to element content -->
|
||||||
<!-- property name="hibernate.ejb.naming_strategy">org.hibernate.ejb.test.MyNamingStrategy</property -->
|
<!-- property name="hibernate.ejb.naming_strategy">org.hibernate.ejb.test.MyNamingStrategy</property -->
|
||||||
|
|
|
@ -12,7 +12,7 @@
|
||||||
<property name="hibernate.connection.password" value="@jdbc.pass@"/>
|
<property name="hibernate.connection.password" value="@jdbc.pass@"/>
|
||||||
<property name="hibernate.connection.url" value="@jdbc.url@"/>
|
<property name="hibernate.connection.url" value="@jdbc.url@"/>
|
||||||
<property name="hibernate.hbm2ddl.auto" value="create-drop"/>
|
<property name="hibernate.hbm2ddl.auto" value="create-drop"/>
|
||||||
<property name="hibernate.cache.provider_class" value="org.hibernate.cache.internal.HashtableCacheProvider"/>
|
<property name="hibernate.cache.region.factory_class" value="org.hibernate.testing.cache.CachingRegionFactory" />
|
||||||
</properties>
|
</properties>
|
||||||
</persistence-unit>
|
</persistence-unit>
|
||||||
</persistence>
|
</persistence>
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
<properties>
|
<properties>
|
||||||
<property name="hibernate.dialect" value="@db.dialect@"/>
|
<property name="hibernate.dialect" value="@db.dialect@"/>
|
||||||
<property name="hibernate.hbm2ddl.auto" value="create-drop"/>
|
<property name="hibernate.hbm2ddl.auto" value="create-drop"/>
|
||||||
<property name="hibernate.cache.provider_class" value="org.hibernate.cache.internal.HashtableCacheProvider"/>
|
<property name="hibernate.cache.region.factory_class" value="org.hibernate.testing.cache.CachingRegionFactory" />
|
||||||
</properties>
|
</properties>
|
||||||
</persistence-unit>
|
</persistence-unit>
|
||||||
</persistence>
|
</persistence>
|
||||||
|
|
|
@ -12,7 +12,7 @@
|
||||||
<property name="hibernate.connection.password" value="@jdbc.pass@"/>
|
<property name="hibernate.connection.password" value="@jdbc.pass@"/>
|
||||||
<property name="hibernate.connection.url" value="@jdbc.url@"/>
|
<property name="hibernate.connection.url" value="@jdbc.url@"/>
|
||||||
<property name="hibernate.hbm2ddl.auto" value="create-drop"/>
|
<property name="hibernate.hbm2ddl.auto" value="create-drop"/>
|
||||||
<property name="hibernate.cache.provider_class" value="org.hibernate.cache.internal.HashtableCacheProvider"/>
|
<property name="hibernate.cache.region.factory_class" value="org.hibernate.testing.cache.CachingRegionFactory" />
|
||||||
</properties>
|
</properties>
|
||||||
</persistence-unit>
|
</persistence-unit>
|
||||||
</persistence>
|
</persistence>
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
<property name="hibernate.connection.password" value="@jdbc.pass@"/>
|
<property name="hibernate.connection.password" value="@jdbc.pass@"/>
|
||||||
<property name="hibernate.connection.url" value="@jdbc.url@"/>
|
<property name="hibernate.connection.url" value="@jdbc.url@"/>
|
||||||
<property name="hibernate.hbm2ddl.auto" value="create-drop"/>
|
<property name="hibernate.hbm2ddl.auto" value="create-drop"/>
|
||||||
<property name="hibernate.cache.provider_class" value="org.hibernate.cache.internal.HashtableCacheProvider"/>
|
<property name="hibernate.cache.region.factory_class" value="org.hibernate.testing.cache.CachingRegionFactory" />
|
||||||
</properties>
|
</properties>
|
||||||
</persistence-unit>
|
</persistence-unit>
|
||||||
</persistence>
|
</persistence>
|
||||||
|
|
|
@ -33,6 +33,6 @@ hibernate.show_sql true
|
||||||
hibernate.max_fetch_depth 5
|
hibernate.max_fetch_depth 5
|
||||||
|
|
||||||
hibernate.cache.region_prefix hibernate.test
|
hibernate.cache.region_prefix hibernate.test
|
||||||
hibernate.cache.provider_class org.hibernate.cache.internal.HashtableCacheProvider
|
hibernate.cache.region.factory_class org.hibernate.testing.cache.CachingRegionFactory
|
||||||
|
|
||||||
hibernate.jdbc.batch_size 0
|
hibernate.jdbc.batch_size 0
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
<property name="hibernate.max_fetch_depth">3</property>
|
<property name="hibernate.max_fetch_depth">3</property>
|
||||||
<property name="hibernate.hbm2ddl.auto">create-drop</property>
|
<property name="hibernate.hbm2ddl.auto">create-drop</property>
|
||||||
<property name="hibernate.generate_statistics">true</property>
|
<property name="hibernate.generate_statistics">true</property>
|
||||||
<property name="hibernate.cache.provider_class">org.hibernate.cache.internal.HashtableCacheProvider</property>
|
<property name="hibernate.cache.region.factory_class">org.hibernate.testing.cache.CachingRegionFactory</property>
|
||||||
<mapping class="org.hibernate.ejb.test.Item"/>
|
<mapping class="org.hibernate.ejb.test.Item"/>
|
||||||
<mapping class="org.hibernate.ejb.test.Cat"/>
|
<mapping class="org.hibernate.ejb.test.Cat"/>
|
||||||
<mapping class="org.hibernate.ejb.test.Kitten"/>
|
<mapping class="org.hibernate.ejb.test.Kitten"/>
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
package org.hibernate.envers.test.integration.cache;
|
package org.hibernate.envers.test.integration.cache;
|
||||||
|
|
||||||
import org.hibernate.MappingException;
|
import org.hibernate.MappingException;
|
||||||
import org.hibernate.cache.internal.EhCacheProvider;
|
import org.hibernate.cache.internal.EhCacheRegionFactory;
|
||||||
import org.hibernate.cfg.Environment;
|
import org.hibernate.cfg.Environment;
|
||||||
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||||
import org.hibernate.envers.RevisionType;
|
import org.hibernate.envers.RevisionType;
|
||||||
|
@ -26,7 +26,7 @@ public class HibernateSecLvlQueryCache extends AbstractSessionTest {
|
||||||
config.addAnnotatedClass(StrTestEntity.class);
|
config.addAnnotatedClass(StrTestEntity.class);
|
||||||
config.setProperty(Environment.USE_SECOND_LEVEL_CACHE, "true");
|
config.setProperty(Environment.USE_SECOND_LEVEL_CACHE, "true");
|
||||||
config.setProperty(Environment.USE_QUERY_CACHE, "true");
|
config.setProperty(Environment.USE_QUERY_CACHE, "true");
|
||||||
config.setProperty(Environment.CACHE_PROVIDER, EhCacheProvider.class.getName());
|
config.setProperty(Environment.CACHE_REGION_FACTORY, EhCacheRegionFactory.class.getName());
|
||||||
config.setProperty(Environment.CACHE_PROVIDER_CONFIG, "ehcache-test.xml");
|
config.setProperty(Environment.CACHE_PROVIDER_CONFIG, "ehcache-test.xml");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
360
hibernate-testing/src/main/java/org/hibernate/testing/cache/AbstractReadWriteAccessStrategy.java
vendored
Normal file
360
hibernate-testing/src/main/java/org/hibernate/testing/cache/AbstractReadWriteAccessStrategy.java
vendored
Normal file
|
@ -0,0 +1,360 @@
|
||||||
|
package org.hibernate.testing.cache;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.Comparator;
|
||||||
|
import java.util.UUID;
|
||||||
|
import java.util.concurrent.atomic.AtomicLong;
|
||||||
|
import java.util.concurrent.locks.ReentrantReadWriteLock;
|
||||||
|
|
||||||
|
import org.jboss.logging.Logger;
|
||||||
|
|
||||||
|
import org.hibernate.cache.CacheException;
|
||||||
|
import org.hibernate.cache.spi.access.SoftLock;
|
||||||
|
import org.hibernate.internal.CoreMessageLogger;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Strong Liu
|
||||||
|
*/
|
||||||
|
abstract class AbstractReadWriteAccessStrategy extends BaseRegionAccessStrategy {
|
||||||
|
private static final CoreMessageLogger LOG = Logger.getMessageLogger(
|
||||||
|
CoreMessageLogger.class, AbstractReadWriteAccessStrategy.class.getName()
|
||||||
|
);
|
||||||
|
private final UUID uuid = UUID.randomUUID();
|
||||||
|
private final AtomicLong nextLockId = new AtomicLong();
|
||||||
|
private ReentrantReadWriteLock reentrantReadWriteLock = new ReentrantReadWriteLock();
|
||||||
|
protected java.util.concurrent.locks.Lock readLock = reentrantReadWriteLock.readLock();
|
||||||
|
protected java.util.concurrent.locks.Lock writeLock = reentrantReadWriteLock.writeLock();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns <code>null</code> if the item is not readable. Locked items are not readable, nor are items created
|
||||||
|
* after the start of this transaction.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public final Object get(Object key, long txTimestamp) throws CacheException {
|
||||||
|
try {
|
||||||
|
readLock.lock();
|
||||||
|
Lockable item = (Lockable) getInternalRegion().get( key );
|
||||||
|
|
||||||
|
boolean readable = item != null && item.isReadable( txTimestamp );
|
||||||
|
if ( readable ) {
|
||||||
|
return item.getValue();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
finally {
|
||||||
|
readLock.unlock();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract Comparator getVersionComparator();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns <code>false</code> and fails to put the value if there is an existing un-writeable item mapped to this
|
||||||
|
* key.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public final boolean putFromLoad(Object key, Object value, long txTimestamp, Object version, boolean minimalPutOverride)
|
||||||
|
throws CacheException {
|
||||||
|
try {
|
||||||
|
writeLock.lock();
|
||||||
|
Lockable item = (Lockable) getInternalRegion().get( key );
|
||||||
|
boolean writeable = item == null || item.isWriteable( txTimestamp, version, getVersionComparator() );
|
||||||
|
if ( writeable ) {
|
||||||
|
getInternalRegion().put( key, new Item( value, version, getInternalRegion().nextTimestamp() ) );
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
finally {
|
||||||
|
writeLock.unlock();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Soft-lock a cache item.
|
||||||
|
*/
|
||||||
|
public final SoftLock lockItem(Object key, Object version) throws CacheException {
|
||||||
|
|
||||||
|
try {
|
||||||
|
writeLock.lock();
|
||||||
|
Lockable item = (Lockable) getInternalRegion().get( key );
|
||||||
|
long timeout = getInternalRegion().nextTimestamp() + getInternalRegion().getTimeout();
|
||||||
|
final Lock lock = ( item == null ) ? new Lock( timeout, uuid, nextLockId(), version ) : item.lock(
|
||||||
|
timeout,
|
||||||
|
uuid,
|
||||||
|
nextLockId()
|
||||||
|
);
|
||||||
|
getInternalRegion().put( key, lock );
|
||||||
|
return lock;
|
||||||
|
}
|
||||||
|
finally {
|
||||||
|
writeLock.unlock();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Soft-unlock a cache item.
|
||||||
|
*/
|
||||||
|
public final void unlockItem(Object key, SoftLock lock) throws CacheException {
|
||||||
|
|
||||||
|
try {
|
||||||
|
writeLock.lock();
|
||||||
|
Lockable item = (Lockable) getInternalRegion().get( key );
|
||||||
|
|
||||||
|
if ( ( item != null ) && item.isUnlockable( lock ) ) {
|
||||||
|
decrementLock( key, (Lock) item );
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
handleLockExpiry( key, item );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
finally {
|
||||||
|
writeLock.unlock();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private long nextLockId() {
|
||||||
|
return nextLockId.getAndIncrement();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unlock and re-put the given key, lock combination.
|
||||||
|
*/
|
||||||
|
protected void decrementLock(Object key, Lock lock) {
|
||||||
|
lock.unlock( getInternalRegion().nextTimestamp() );
|
||||||
|
getInternalRegion().put( key, lock );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle the timeout of a previous lock mapped to this key
|
||||||
|
*/
|
||||||
|
protected void handleLockExpiry(Object key, Lockable lock) {
|
||||||
|
LOG.expired(key);
|
||||||
|
long ts = getInternalRegion().nextTimestamp() + getInternalRegion().getTimeout();
|
||||||
|
// create new lock that times out immediately
|
||||||
|
Lock newLock = new Lock( ts, uuid, nextLockId.getAndIncrement(), null );
|
||||||
|
newLock.unlock( ts );
|
||||||
|
getInternalRegion().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 final static 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
public boolean isReadable(long txTimestamp) {
|
||||||
|
return txTimestamp > timestamp;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
public boolean isWriteable(long txTimestamp, Object newVersion, Comparator versionComparator) {
|
||||||
|
return version != null && versionComparator.compare( version, newVersion ) < 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
public Object getValue() {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
public boolean isUnlockable(SoftLock lock) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
public Lock lock(long timeout, UUID uuid, long lockId) {
|
||||||
|
return new Lock( timeout, uuid, lockId, version );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Wrapper type representing locked items.
|
||||||
|
*/
|
||||||
|
protected final static 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.
|
||||||
|
*/
|
||||||
|
Lock(long timeout, UUID sourceUuid, long lockId, Object version) {
|
||||||
|
this.timeout = timeout;
|
||||||
|
this.lockId = lockId;
|
||||||
|
this.version = version;
|
||||||
|
this.sourceUuid = sourceUuid;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
public boolean isReadable(long txTimestamp) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
public Object getValue() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
public boolean isUnlockable(SoftLock lock) {
|
||||||
|
return equals( lock );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
public String toString() {
|
||||||
|
StringBuilder sb = new StringBuilder( "Lock Source-UUID:" + sourceUuid + " Lock-ID:" + lockId );
|
||||||
|
return sb.toString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
* Hibernate, Relational Persistence for Idiomatic Java
|
* Hibernate, Relational Persistence for Idiomatic Java
|
||||||
*
|
*
|
||||||
* Copyright (c) 2008-2011, Red Hat Inc. or third-party contributors as
|
* Copyright (c) 2010-2011, Red Hat Inc. or third-party contributors as
|
||||||
* indicated by the @author tags or express copyright attribution
|
* indicated by the @author tags or express copyright attribution
|
||||||
* statements applied by the authors. All third-party contributions are
|
* statements applied by the authors. All third-party contributions are
|
||||||
* distributed under license by Red Hat Inc.
|
* distributed under license by Red Hat Inc.
|
||||||
|
@ -21,37 +21,34 @@
|
||||||
* 51 Franklin Street, Fifth Floor
|
* 51 Franklin Street, Fifth Floor
|
||||||
* Boston, MA 02110-1301 USA
|
* Boston, MA 02110-1301 USA
|
||||||
*/
|
*/
|
||||||
package org.hibernate.cache.internal.bridge;
|
package org.hibernate.testing.cache;
|
||||||
|
|
||||||
import org.hibernate.cache.CacheException;
|
import org.hibernate.cache.spi.CollectionRegion;
|
||||||
import org.hibernate.cache.spi.Cache;
|
|
||||||
import org.hibernate.cache.spi.GeneralDataRegion;
|
import org.hibernate.cache.spi.GeneralDataRegion;
|
||||||
import org.hibernate.cfg.Settings;
|
import org.hibernate.cache.spi.access.CollectionRegionAccessStrategy;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@inheritDoc}
|
* @author Strong Liu
|
||||||
*
|
|
||||||
* @author Steve Ebersole
|
|
||||||
*/
|
*/
|
||||||
public abstract class BaseGeneralDataRegionAdapter extends BaseRegionAdapter implements GeneralDataRegion {
|
class BaseCollectionRegionAccessStrategy extends BaseRegionAccessStrategy implements CollectionRegionAccessStrategy {
|
||||||
|
private final CollectionRegionImpl region;
|
||||||
|
|
||||||
protected BaseGeneralDataRegionAdapter(Cache underlyingCache, Settings settings) {
|
@Override
|
||||||
super( underlyingCache, settings );
|
protected BaseGeneralDataRegion getInternalRegion() {
|
||||||
|
return region;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Object get(Object key) throws CacheException {
|
@Override
|
||||||
return underlyingCache.get( key );
|
protected boolean isDefaultMinimalPutOverride() {
|
||||||
|
return region.getSettings().isMinimalPutsEnabled();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void put(Object key, Object value) throws CacheException {
|
@Override
|
||||||
underlyingCache.put( key, value );
|
public CollectionRegion getRegion() {
|
||||||
|
return region;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void evict(Object key) throws CacheException {
|
BaseCollectionRegionAccessStrategy(CollectionRegionImpl region) {
|
||||||
underlyingCache.remove( key );
|
this.region = region;
|
||||||
}
|
|
||||||
|
|
||||||
public void evictAll() throws CacheException {
|
|
||||||
underlyingCache.clear();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
85
hibernate-testing/src/main/java/org/hibernate/testing/cache/BaseEntityRegionAccessStrategy.java
vendored
Normal file
85
hibernate-testing/src/main/java/org/hibernate/testing/cache/BaseEntityRegionAccessStrategy.java
vendored
Normal file
|
@ -0,0 +1,85 @@
|
||||||
|
/*
|
||||||
|
* Hibernate, Relational Persistence for Idiomatic Java
|
||||||
|
*
|
||||||
|
* Copyright (c) 2010-2011, Red Hat Inc. or third-party contributors as
|
||||||
|
* indicated by the @author tags or express copyright attribution
|
||||||
|
* statements applied by the authors. All third-party contributions are
|
||||||
|
* distributed under license by Red Hat Inc.
|
||||||
|
*
|
||||||
|
* This copyrighted material is made available to anyone wishing to use, modify,
|
||||||
|
* copy, or redistribute it subject to the terms and conditions of the GNU
|
||||||
|
* Lesser General Public License, as published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||||
|
* for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with this distribution; if not, write to:
|
||||||
|
* Free Software Foundation, Inc.
|
||||||
|
* 51 Franklin Street, Fifth Floor
|
||||||
|
* Boston, MA 02110-1301 USA
|
||||||
|
*/
|
||||||
|
package org.hibernate.testing.cache;
|
||||||
|
|
||||||
|
import org.jboss.logging.Logger;
|
||||||
|
|
||||||
|
import org.hibernate.cache.CacheException;
|
||||||
|
import org.hibernate.cache.spi.EntityRegion;
|
||||||
|
import org.hibernate.cache.spi.GeneralDataRegion;
|
||||||
|
import org.hibernate.cache.spi.access.EntityRegionAccessStrategy;
|
||||||
|
import org.hibernate.cache.spi.access.SoftLock;
|
||||||
|
import org.hibernate.internal.CoreMessageLogger;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Strong Liu
|
||||||
|
*/
|
||||||
|
class BaseEntityRegionAccessStrategy extends BaseRegionAccessStrategy implements EntityRegionAccessStrategy {
|
||||||
|
private static final CoreMessageLogger LOG = Logger.getMessageLogger(
|
||||||
|
CoreMessageLogger.class, BaseEntityRegionAccessStrategy.class.getName()
|
||||||
|
);
|
||||||
|
private final EntityRegionImpl region;
|
||||||
|
|
||||||
|
BaseEntityRegionAccessStrategy(EntityRegionImpl region) {
|
||||||
|
this.region = region;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public EntityRegion getRegion() {
|
||||||
|
return region;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean insert(Object key, Object value, Object version) throws CacheException {
|
||||||
|
return putFromLoad( key, value, 0, version );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean afterInsert(Object key, Object value, Object version) throws CacheException {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean update(Object key, Object value, Object currentVersion, Object previousVersion)
|
||||||
|
throws CacheException {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean afterUpdate(Object key, Object value, Object currentVersion, Object previousVersion, SoftLock lock)
|
||||||
|
throws CacheException {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected BaseGeneralDataRegion getInternalRegion() {
|
||||||
|
return region;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected boolean isDefaultMinimalPutOverride() {
|
||||||
|
return region.getSettings().isMinimalPutsEnabled();
|
||||||
|
}
|
||||||
|
}
|
91
hibernate-testing/src/main/java/org/hibernate/testing/cache/BaseGeneralDataRegion.java
vendored
Normal file
91
hibernate-testing/src/main/java/org/hibernate/testing/cache/BaseGeneralDataRegion.java
vendored
Normal file
|
@ -0,0 +1,91 @@
|
||||||
|
/*
|
||||||
|
* Hibernate, Relational Persistence for Idiomatic Java
|
||||||
|
*
|
||||||
|
* Copyright (c) 2010-2011, Red Hat Inc. or third-party contributors as
|
||||||
|
* indicated by the @author tags or express copyright attribution
|
||||||
|
* statements applied by the authors. All third-party contributions are
|
||||||
|
* distributed under license by Red Hat Inc.
|
||||||
|
*
|
||||||
|
* This copyrighted material is made available to anyone wishing to use, modify,
|
||||||
|
* copy, or redistribute it subject to the terms and conditions of the GNU
|
||||||
|
* Lesser General Public License, as published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||||
|
* for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with this distribution; if not, write to:
|
||||||
|
* Free Software Foundation, Inc.
|
||||||
|
* 51 Franklin Street, Fifth Floor
|
||||||
|
* Boston, MA 02110-1301 USA
|
||||||
|
*/
|
||||||
|
package org.hibernate.testing.cache;
|
||||||
|
|
||||||
|
import java.util.concurrent.locks.Lock;
|
||||||
|
import java.util.concurrent.locks.ReentrantReadWriteLock;
|
||||||
|
|
||||||
|
import org.jboss.logging.Logger;
|
||||||
|
|
||||||
|
import org.hibernate.cache.CacheException;
|
||||||
|
import org.hibernate.cache.spi.GeneralDataRegion;
|
||||||
|
import org.hibernate.internal.CoreMessageLogger;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Strong Liu
|
||||||
|
*/
|
||||||
|
class BaseGeneralDataRegion extends BaseRegion implements GeneralDataRegion {
|
||||||
|
private static final CoreMessageLogger LOG = Logger.getMessageLogger(
|
||||||
|
CoreMessageLogger.class, BaseGeneralDataRegion.class.getName()
|
||||||
|
);
|
||||||
|
|
||||||
|
BaseGeneralDataRegion(String name) {
|
||||||
|
super( name );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object get(Object key) throws CacheException {
|
||||||
|
LOG.debugf( "Cache lookup : key[%s]", key );
|
||||||
|
if ( key == null ) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
Object result = cache.get( key );
|
||||||
|
if ( result != null ) {
|
||||||
|
LOG.debugf( "Cache hit: %s", key );
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void put(Object key, Object value) throws CacheException {
|
||||||
|
LOG.debugf( "Caching : [%s] -> [%s]", key, value );
|
||||||
|
if ( key == null || value == null ) {
|
||||||
|
LOG.debug( "Key or Value is null" );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
cache.put( key, value );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void evict(Object key) throws CacheException {
|
||||||
|
LOG.debugf( "Invalidating: %s", key );
|
||||||
|
if ( key == null ) {
|
||||||
|
LOG.debug( "Key is null" );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
cache.remove( key );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void evictAll() throws CacheException {
|
||||||
|
LOG.debug( "evict cache" );
|
||||||
|
cache.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
* Hibernate, Relational Persistence for Idiomatic Java
|
* Hibernate, Relational Persistence for Idiomatic Java
|
||||||
*
|
*
|
||||||
* Copyright (c) 2008-2011, Red Hat Inc. or third-party contributors as
|
* Copyright (c) 2010-2011, Red Hat Inc. or third-party contributors as
|
||||||
* indicated by the @author tags or express copyright attribution
|
* indicated by the @author tags or express copyright attribution
|
||||||
* statements applied by the authors. All third-party contributions are
|
* statements applied by the authors. All third-party contributions are
|
||||||
* distributed under license by Red Hat Inc.
|
* distributed under license by Red Hat Inc.
|
||||||
|
@ -21,67 +21,72 @@
|
||||||
* 51 Franklin Street, Fifth Floor
|
* 51 Franklin Street, Fifth Floor
|
||||||
* Boston, MA 02110-1301 USA
|
* Boston, MA 02110-1301 USA
|
||||||
*/
|
*/
|
||||||
package org.hibernate.cache.internal.bridge;
|
package org.hibernate.testing.cache;
|
||||||
|
|
||||||
|
import java.util.Collections;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
|
||||||
import org.hibernate.cache.CacheException;
|
import org.hibernate.cache.CacheException;
|
||||||
import org.hibernate.cache.spi.Cache;
|
import org.hibernate.cache.internal.Timestamper;
|
||||||
import org.hibernate.cache.spi.Region;
|
import org.hibernate.cache.spi.Region;
|
||||||
import org.hibernate.cfg.Settings;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Basic adapter bridging between {@link Region} and {@link Cache}.
|
* @author Strong Liu
|
||||||
*
|
|
||||||
* @author Steve Ebersole
|
|
||||||
*/
|
*/
|
||||||
public abstract class BaseRegionAdapter implements Region {
|
class BaseRegion implements Region {
|
||||||
protected final Cache underlyingCache;
|
protected final Map cache = new ConcurrentHashMap();
|
||||||
protected final Settings settings;
|
private final String name;
|
||||||
|
|
||||||
protected BaseRegionAdapter(Cache underlyingCache, Settings settings) {
|
BaseRegion(String name) {
|
||||||
this.underlyingCache = underlyingCache;
|
this.name = name;
|
||||||
this.settings = settings;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getName() {
|
|
||||||
return underlyingCache.getRegionName();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void clear() throws CacheException {
|
|
||||||
underlyingCache.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void destroy() throws CacheException {
|
|
||||||
underlyingCache.destroy();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public boolean contains(Object key) {
|
public boolean contains(Object key) {
|
||||||
// safer to utilize the toMap() as oposed to say get(key) != null
|
return key != null ? cache.containsKey( key ) : false;
|
||||||
return underlyingCache.toMap().containsKey( key );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void destroy() throws CacheException {
|
||||||
|
cache.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public long getSizeInMemory() {
|
public long getSizeInMemory() {
|
||||||
return underlyingCache.getSizeInMemory();
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public long getElementCountInMemory() {
|
public long getElementCountInMemory() {
|
||||||
return underlyingCache.getElementCountInMemory();
|
return cache.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public long getElementCountOnDisk() {
|
public long getElementCountOnDisk() {
|
||||||
return underlyingCache.getElementCountOnDisk();
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public Map toMap() {
|
public Map toMap() {
|
||||||
return underlyingCache.toMap();
|
return Collections.unmodifiableMap( cache );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public long nextTimestamp() {
|
public long nextTimestamp() {
|
||||||
return underlyingCache.nextTimestamp();
|
return Timestamper.next();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public int getTimeout() {
|
public int getTimeout() {
|
||||||
return underlyingCache.getTimeout();
|
return Timestamper.ONE_MS * 60000;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
109
hibernate-testing/src/main/java/org/hibernate/testing/cache/BaseRegionAccessStrategy.java
vendored
Normal file
109
hibernate-testing/src/main/java/org/hibernate/testing/cache/BaseRegionAccessStrategy.java
vendored
Normal file
|
@ -0,0 +1,109 @@
|
||||||
|
/*
|
||||||
|
* Hibernate, Relational Persistence for Idiomatic Java
|
||||||
|
*
|
||||||
|
* Copyright (c) 2010-2011, Red Hat Inc. or third-party contributors as
|
||||||
|
* indicated by the @author tags or express copyright attribution
|
||||||
|
* statements applied by the authors. All third-party contributions are
|
||||||
|
* distributed under license by Red Hat Inc.
|
||||||
|
*
|
||||||
|
* This copyrighted material is made available to anyone wishing to use, modify,
|
||||||
|
* copy, or redistribute it subject to the terms and conditions of the GNU
|
||||||
|
* Lesser General Public License, as published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||||
|
* for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with this distribution; if not, write to:
|
||||||
|
* Free Software Foundation, Inc.
|
||||||
|
* 51 Franklin Street, Fifth Floor
|
||||||
|
* Boston, MA 02110-1301 USA
|
||||||
|
*/
|
||||||
|
package org.hibernate.testing.cache;
|
||||||
|
|
||||||
|
import org.jboss.logging.Logger;
|
||||||
|
|
||||||
|
import org.hibernate.cache.CacheException;
|
||||||
|
import org.hibernate.cache.spi.GeneralDataRegion;
|
||||||
|
import org.hibernate.cache.spi.access.RegionAccessStrategy;
|
||||||
|
import org.hibernate.cache.spi.access.SoftLock;
|
||||||
|
import org.hibernate.internal.CoreMessageLogger;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Strong Liu
|
||||||
|
*/
|
||||||
|
abstract class BaseRegionAccessStrategy implements RegionAccessStrategy {
|
||||||
|
private static final CoreMessageLogger LOG = Logger.getMessageLogger(
|
||||||
|
CoreMessageLogger.class, BaseRegionAccessStrategy.class.getName()
|
||||||
|
);
|
||||||
|
|
||||||
|
protected abstract BaseGeneralDataRegion getInternalRegion();
|
||||||
|
protected abstract boolean isDefaultMinimalPutOverride();
|
||||||
|
@Override
|
||||||
|
public Object get(Object key, long txTimestamp) throws CacheException {
|
||||||
|
return getInternalRegion().get( key );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean putFromLoad(Object key, Object value, long txTimestamp, Object version) throws CacheException {
|
||||||
|
return putFromLoad( key, value, txTimestamp, version, isDefaultMinimalPutOverride() );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean putFromLoad(Object key, Object value, long txTimestamp, Object version, boolean minimalPutOverride)
|
||||||
|
throws CacheException {
|
||||||
|
|
||||||
|
if ( key == null || value == null ) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if ( minimalPutOverride && getInternalRegion().contains( key ) ) {
|
||||||
|
LOG.debugf( "Item already cached: %s", key );
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
LOG.debugf( "Caching: %s", key );
|
||||||
|
getInternalRegion().put( key, value );
|
||||||
|
return true;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SoftLock lockItem(Object key, Object version) throws CacheException {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SoftLock lockRegion() throws CacheException {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void unlockItem(Object key, SoftLock lock) throws CacheException {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void unlockRegion(SoftLock lock) throws CacheException {
|
||||||
|
evictAll();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void remove(Object key) throws CacheException {
|
||||||
|
evict( key );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void removeAll() throws CacheException {
|
||||||
|
evictAll();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void evict(Object key) throws CacheException {
|
||||||
|
getInternalRegion().evict( key );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void evictAll() throws CacheException {
|
||||||
|
getInternalRegion().evictAll();
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
* Hibernate, Relational Persistence for Idiomatic Java
|
* Hibernate, Relational Persistence for Idiomatic Java
|
||||||
*
|
*
|
||||||
* Copyright (c) 2008-2011, Red Hat Inc. or third-party contributors as
|
* Copyright (c) 2010-2011, Red Hat Inc. or third-party contributors as
|
||||||
* indicated by the @author tags or express copyright attribution
|
* indicated by the @author tags or express copyright attribution
|
||||||
* statements applied by the authors. All third-party contributions are
|
* statements applied by the authors. All third-party contributions are
|
||||||
* distributed under license by Red Hat Inc.
|
* distributed under license by Red Hat Inc.
|
||||||
|
@ -21,35 +21,30 @@
|
||||||
* 51 Franklin Street, Fifth Floor
|
* 51 Franklin Street, Fifth Floor
|
||||||
* Boston, MA 02110-1301 USA
|
* Boston, MA 02110-1301 USA
|
||||||
*/
|
*/
|
||||||
package org.hibernate.cache.internal.bridge;
|
package org.hibernate.testing.cache;
|
||||||
|
|
||||||
import org.hibernate.cache.spi.Cache;
|
|
||||||
import org.hibernate.cache.spi.CacheDataDescription;
|
import org.hibernate.cache.spi.CacheDataDescription;
|
||||||
import org.hibernate.cache.spi.TransactionAwareCache;
|
|
||||||
import org.hibernate.cache.spi.TransactionalDataRegion;
|
import org.hibernate.cache.spi.TransactionalDataRegion;
|
||||||
import org.hibernate.cfg.Settings;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@inheritDoc}
|
* @author Strong Liu
|
||||||
*
|
|
||||||
* @author Steve Ebersole
|
|
||||||
*/
|
*/
|
||||||
public abstract class BaseTransactionalDataRegionAdapter
|
class BaseTransactionalDataRegion extends BaseGeneralDataRegion implements TransactionalDataRegion {
|
||||||
extends BaseRegionAdapter
|
private final CacheDataDescription metadata;
|
||||||
implements TransactionalDataRegion {
|
|
||||||
|
|
||||||
protected final CacheDataDescription metadata;
|
BaseTransactionalDataRegion(String name, CacheDataDescription metadata) {
|
||||||
|
super( name );
|
||||||
protected BaseTransactionalDataRegionAdapter(Cache underlyingCache, Settings settings, CacheDataDescription metadata) {
|
|
||||||
super( underlyingCache, settings );
|
|
||||||
this.metadata = metadata;
|
this.metadata = metadata;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isTransactionAware() {
|
@Override
|
||||||
return underlyingCache instanceof TransactionAwareCache;
|
|
||||||
}
|
|
||||||
|
|
||||||
public CacheDataDescription getCacheDataDescription() {
|
public CacheDataDescription getCacheDataDescription() {
|
||||||
return metadata;
|
return metadata;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isTransactionAware() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
116
hibernate-testing/src/main/java/org/hibernate/testing/cache/CachingRegionFactory.java
vendored
Normal file
116
hibernate-testing/src/main/java/org/hibernate/testing/cache/CachingRegionFactory.java
vendored
Normal file
|
@ -0,0 +1,116 @@
|
||||||
|
/*
|
||||||
|
* Hibernate, Relational Persistence for Idiomatic Java
|
||||||
|
*
|
||||||
|
* Copyright (c) 2010-2011, Red Hat Inc. or third-party contributors as
|
||||||
|
* indicated by the @author tags or express copyright attribution
|
||||||
|
* statements applied by the authors. All third-party contributions are
|
||||||
|
* distributed under license by Red Hat Inc.
|
||||||
|
*
|
||||||
|
* This copyrighted material is made available to anyone wishing to use, modify,
|
||||||
|
* copy, or redistribute it subject to the terms and conditions of the GNU
|
||||||
|
* Lesser General Public License, as published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||||
|
* for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with this distribution; if not, write to:
|
||||||
|
* Free Software Foundation, Inc.
|
||||||
|
* 51 Franklin Street, Fifth Floor
|
||||||
|
* Boston, MA 02110-1301 USA
|
||||||
|
*/
|
||||||
|
package org.hibernate.testing.cache;
|
||||||
|
|
||||||
|
import java.util.Properties;
|
||||||
|
|
||||||
|
import org.jboss.logging.Logger;
|
||||||
|
|
||||||
|
import org.hibernate.cache.CacheException;
|
||||||
|
import org.hibernate.cache.internal.Timestamper;
|
||||||
|
import org.hibernate.cache.spi.CacheDataDescription;
|
||||||
|
import org.hibernate.cache.spi.CollectionRegion;
|
||||||
|
import org.hibernate.cache.spi.EntityRegion;
|
||||||
|
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.cfg.Settings;
|
||||||
|
import org.hibernate.internal.CoreMessageLogger;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Strong Liu
|
||||||
|
*/
|
||||||
|
public class CachingRegionFactory implements RegionFactory {
|
||||||
|
private static final CoreMessageLogger LOG = Logger.getMessageLogger(
|
||||||
|
CoreMessageLogger.class, CachingRegionFactory.class.getName()
|
||||||
|
);
|
||||||
|
private Settings settings;
|
||||||
|
public CachingRegionFactory() {
|
||||||
|
LOG.warn( "CachingRegionFactory should be only used for testing." );
|
||||||
|
}
|
||||||
|
|
||||||
|
public CachingRegionFactory(Properties properties) {
|
||||||
|
//add here to avoid run into catch
|
||||||
|
LOG.warn( "CachingRegionFactory should be only used for testing." );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void start(Settings settings, Properties properties) throws CacheException {
|
||||||
|
this.settings=settings;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void stop() {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isMinimalPutsEnabledByDefault() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public AccessType getDefaultAccessType() {
|
||||||
|
return AccessType.NONSTRICT_READ_WRITE;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long nextTimestamp() {
|
||||||
|
return Timestamper.next();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public EntityRegion buildEntityRegion(String regionName, Properties properties, CacheDataDescription metadata)
|
||||||
|
throws CacheException {
|
||||||
|
return new EntityRegionImpl( regionName, metadata, settings );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CollectionRegion buildCollectionRegion(String regionName, Properties properties, CacheDataDescription metadata)
|
||||||
|
throws CacheException {
|
||||||
|
return new CollectionRegionImpl( regionName, metadata, settings );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public QueryResultsRegion buildQueryResultsRegion(String regionName, Properties properties) throws CacheException {
|
||||||
|
return new QueryResultsRegionImpl( regionName );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public TimestampsRegion buildTimestampsRegion(String regionName, Properties properties) throws CacheException {
|
||||||
|
return new TimestampsRegionImpl( regionName );
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class QueryResultsRegionImpl extends BaseGeneralDataRegion implements QueryResultsRegion {
|
||||||
|
QueryResultsRegionImpl(String name) {
|
||||||
|
super( name );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class TimestampsRegionImpl extends BaseGeneralDataRegion implements TimestampsRegion {
|
||||||
|
TimestampsRegionImpl(String name) {
|
||||||
|
super( name );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
74
hibernate-testing/src/main/java/org/hibernate/testing/cache/CollectionRegionImpl.java
vendored
Normal file
74
hibernate-testing/src/main/java/org/hibernate/testing/cache/CollectionRegionImpl.java
vendored
Normal file
|
@ -0,0 +1,74 @@
|
||||||
|
/*
|
||||||
|
* Hibernate, Relational Persistence for Idiomatic Java
|
||||||
|
*
|
||||||
|
* Copyright (c) 2010-2011, Red Hat Inc. or third-party contributors as
|
||||||
|
* indicated by the @author tags or express copyright attribution
|
||||||
|
* statements applied by the authors. All third-party contributions are
|
||||||
|
* distributed under license by Red Hat Inc.
|
||||||
|
*
|
||||||
|
* This copyrighted material is made available to anyone wishing to use, modify,
|
||||||
|
* copy, or redistribute it subject to the terms and conditions of the GNU
|
||||||
|
* Lesser General Public License, as published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||||
|
* for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with this distribution; if not, write to:
|
||||||
|
* Free Software Foundation, Inc.
|
||||||
|
* 51 Franklin Street, Fifth Floor
|
||||||
|
* Boston, MA 02110-1301 USA
|
||||||
|
*/
|
||||||
|
package org.hibernate.testing.cache;
|
||||||
|
|
||||||
|
import org.jboss.logging.Logger;
|
||||||
|
|
||||||
|
import org.hibernate.cache.CacheException;
|
||||||
|
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;
|
||||||
|
import org.hibernate.cfg.Settings;
|
||||||
|
import org.hibernate.internal.CoreMessageLogger;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Strong Liu
|
||||||
|
*/
|
||||||
|
class CollectionRegionImpl extends BaseTransactionalDataRegion implements CollectionRegion {
|
||||||
|
private static final CoreMessageLogger LOG = Logger.getMessageLogger(
|
||||||
|
CoreMessageLogger.class, CollectionRegionImpl.class.getName()
|
||||||
|
);
|
||||||
|
private final Settings settings;
|
||||||
|
CollectionRegionImpl(String name, CacheDataDescription metadata, Settings settings) {
|
||||||
|
super( name, metadata );
|
||||||
|
this.settings=settings;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Settings getSettings() {
|
||||||
|
return settings;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CollectionRegionAccessStrategy buildAccessStrategy(AccessType accessType) throws CacheException {
|
||||||
|
switch ( accessType ) {
|
||||||
|
case READ_ONLY:
|
||||||
|
if ( getCacheDataDescription().isMutable() ) {
|
||||||
|
LOG.warnf( "read-only cache configured for mutable collection [ %s ]", getName() );
|
||||||
|
}
|
||||||
|
return new ReadOnlyCollectionRegionAccessStrategy( this );
|
||||||
|
case READ_WRITE:
|
||||||
|
return new ReadWriteCollectionRegionAccessStrategy( this );
|
||||||
|
case NONSTRICT_READ_WRITE:
|
||||||
|
return new NonstrictReadWriteCollectionRegionAccessStrategy( this );
|
||||||
|
case TRANSACTIONAL:
|
||||||
|
|
||||||
|
throw new UnsupportedOperationException( "doesn't support this access strategy" );
|
||||||
|
default:
|
||||||
|
throw new IllegalArgumentException( "unrecognized access strategy type [" + accessType + "]" );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
78
hibernate-testing/src/main/java/org/hibernate/testing/cache/EntityRegionImpl.java
vendored
Normal file
78
hibernate-testing/src/main/java/org/hibernate/testing/cache/EntityRegionImpl.java
vendored
Normal file
|
@ -0,0 +1,78 @@
|
||||||
|
/*
|
||||||
|
* Hibernate, Relational Persistence for Idiomatic Java
|
||||||
|
*
|
||||||
|
* Copyright (c) 2010-2011, Red Hat Inc. or third-party contributors as
|
||||||
|
* indicated by the @author tags or express copyright attribution
|
||||||
|
* statements applied by the authors. All third-party contributions are
|
||||||
|
* distributed under license by Red Hat Inc.
|
||||||
|
*
|
||||||
|
* This copyrighted material is made available to anyone wishing to use, modify,
|
||||||
|
* copy, or redistribute it subject to the terms and conditions of the GNU
|
||||||
|
* Lesser General Public License, as published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||||
|
* for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with this distribution; if not, write to:
|
||||||
|
* Free Software Foundation, Inc.
|
||||||
|
* 51 Franklin Street, Fifth Floor
|
||||||
|
* Boston, MA 02110-1301 USA
|
||||||
|
*/
|
||||||
|
package org.hibernate.testing.cache;
|
||||||
|
|
||||||
|
import org.jboss.logging.Logger;
|
||||||
|
|
||||||
|
import org.hibernate.cache.CacheException;
|
||||||
|
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;
|
||||||
|
import org.hibernate.cfg.Settings;
|
||||||
|
import org.hibernate.internal.CoreMessageLogger;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Strong Liu
|
||||||
|
*/
|
||||||
|
class EntityRegionImpl extends BaseTransactionalDataRegion implements EntityRegion {
|
||||||
|
private static final CoreMessageLogger LOG = Logger.getMessageLogger(
|
||||||
|
CoreMessageLogger.class, EntityRegionImpl.class.getName()
|
||||||
|
);
|
||||||
|
private final Settings settings;
|
||||||
|
|
||||||
|
|
||||||
|
EntityRegionImpl(String name, CacheDataDescription metadata, Settings settings) {
|
||||||
|
super( name, metadata );
|
||||||
|
this.settings = settings;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public Settings getSettings() {
|
||||||
|
return settings;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public EntityRegionAccessStrategy buildAccessStrategy(AccessType accessType) throws CacheException {
|
||||||
|
switch ( accessType ) {
|
||||||
|
case READ_ONLY:
|
||||||
|
if ( getCacheDataDescription().isMutable() ) {
|
||||||
|
LOG.warnf( "read-only cache configured for mutable entity [ %s ]", getName() );
|
||||||
|
}
|
||||||
|
return new ReadOnlyEntityRegionAccessStrategy( this );
|
||||||
|
case READ_WRITE:
|
||||||
|
return new ReadWriteEntityRegionAccessStrategy( this );
|
||||||
|
case NONSTRICT_READ_WRITE:
|
||||||
|
return new NonstrictReadWriteEntityRegionAccessStrategy( this );
|
||||||
|
case TRANSACTIONAL:
|
||||||
|
// throw new UnsupportedOperationException( "doesn't support this access strategy" );
|
||||||
|
return new NonstrictReadWriteEntityRegionAccessStrategy( this );
|
||||||
|
|
||||||
|
default:
|
||||||
|
throw new IllegalArgumentException( "unrecognized access strategy type [" + accessType + "]" );
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
* Hibernate, Relational Persistence for Idiomatic Java
|
* Hibernate, Relational Persistence for Idiomatic Java
|
||||||
*
|
*
|
||||||
* Copyright (c) 2008-2011, Red Hat Inc. or third-party contributors as
|
* Copyright (c) 2011, Red Hat Inc. or third-party contributors as
|
||||||
* indicated by the @author tags or express copyright attribution
|
* indicated by the @author tags or express copyright attribution
|
||||||
* statements applied by the authors. All third-party contributions are
|
* statements applied by the authors. All third-party contributions are
|
||||||
* distributed under license by Red Hat Inc.
|
* distributed under license by Red Hat Inc.
|
||||||
|
@ -21,30 +21,28 @@
|
||||||
* 51 Franklin Street, Fifth Floor
|
* 51 Franklin Street, Fifth Floor
|
||||||
* Boston, MA 02110-1301 USA
|
* Boston, MA 02110-1301 USA
|
||||||
*/
|
*/
|
||||||
package org.hibernate.cache.internal.bridge;
|
package org.hibernate.testing.cache;
|
||||||
|
|
||||||
import java.util.Comparator;
|
import org.jboss.logging.Logger;
|
||||||
|
|
||||||
import org.hibernate.cache.spi.CacheDataDescription;
|
import org.hibernate.cache.CacheException;
|
||||||
import org.hibernate.cache.spi.OptimisticCacheSource;
|
import org.hibernate.cache.spi.access.SoftLock;
|
||||||
|
import org.hibernate.internal.CoreMessageLogger;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@inheritDoc}
|
* @author Strong Liu
|
||||||
*
|
|
||||||
* @author Steve Ebersole
|
|
||||||
*/
|
*/
|
||||||
public class OptimisticCacheSourceAdapter implements OptimisticCacheSource {
|
class NonstrictReadWriteCollectionRegionAccessStrategy extends BaseCollectionRegionAccessStrategy {
|
||||||
private final CacheDataDescription dataDescription;
|
private static final CoreMessageLogger LOG = Logger.getMessageLogger(
|
||||||
|
CoreMessageLogger.class, NonstrictReadWriteCollectionRegionAccessStrategy.class.getName()
|
||||||
|
);
|
||||||
|
|
||||||
public OptimisticCacheSourceAdapter(CacheDataDescription dataDescription) {
|
NonstrictReadWriteCollectionRegionAccessStrategy(CollectionRegionImpl region) {
|
||||||
this.dataDescription = dataDescription;
|
super( region );
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public void unlockItem(Object key, SoftLock lock) throws CacheException {
|
||||||
|
evict( key );
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isVersioned() {
|
|
||||||
return dataDescription.isVersioned();
|
|
||||||
}
|
|
||||||
|
|
||||||
public Comparator getVersionComparator() {
|
|
||||||
return dataDescription.getVersionComparator();
|
|
||||||
}
|
|
||||||
}
|
}
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
* Hibernate, Relational Persistence for Idiomatic Java
|
* Hibernate, Relational Persistence for Idiomatic Java
|
||||||
*
|
*
|
||||||
* Copyright (c) 2008-2011, Red Hat Inc. or third-party contributors as
|
* Copyright (c) 2011, Red Hat Inc. or third-party contributors as
|
||||||
* indicated by the @author tags or express copyright attribution
|
* indicated by the @author tags or express copyright attribution
|
||||||
* statements applied by the authors. All third-party contributions are
|
* statements applied by the authors. All third-party contributions are
|
||||||
* distributed under license by Red Hat Inc.
|
* distributed under license by Red Hat Inc.
|
||||||
|
@ -21,48 +21,41 @@
|
||||||
* 51 Franklin Street, Fifth Floor
|
* 51 Franklin Street, Fifth Floor
|
||||||
* Boston, MA 02110-1301 USA
|
* Boston, MA 02110-1301 USA
|
||||||
*/
|
*/
|
||||||
package org.hibernate.cache.internal;
|
package org.hibernate.testing.cache;
|
||||||
|
|
||||||
import java.util.Properties;
|
import org.jboss.logging.Logger;
|
||||||
|
|
||||||
import org.hibernate.cache.CacheException;
|
import org.hibernate.cache.CacheException;
|
||||||
import org.hibernate.cache.spi.Cache;
|
import org.hibernate.cache.spi.access.SoftLock;
|
||||||
import org.hibernate.cache.spi.CacheProvider;
|
import org.hibernate.internal.CoreMessageLogger;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A simple in-memory Hashtable-based cache impl.
|
* @author Strong Liu
|
||||||
*
|
|
||||||
* @author Gavin King
|
|
||||||
*/
|
*/
|
||||||
public class HashtableCacheProvider implements CacheProvider {
|
class NonstrictReadWriteEntityRegionAccessStrategy extends BaseEntityRegionAccessStrategy {
|
||||||
|
NonstrictReadWriteEntityRegionAccessStrategy(EntityRegionImpl region) {
|
||||||
public Cache buildCache(String regionName, Properties properties) throws CacheException {
|
super( region );
|
||||||
return new HashtableCache( regionName );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public long nextTimestamp() {
|
@Override
|
||||||
return Timestamper.next();
|
public void unlockItem(Object key, SoftLock lock) throws CacheException {
|
||||||
|
evict( key );
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
@Override
|
||||||
* Callback to perform any necessary initialization of the underlying cache implementation
|
public boolean insert(Object key, Object value, Object version) throws CacheException {
|
||||||
* during SessionFactory construction.
|
|
||||||
*
|
|
||||||
* @param properties current configuration settings.
|
|
||||||
*/
|
|
||||||
public void start(Properties properties) throws CacheException {
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Callback to perform any necessary cleanup of the underlying cache implementation
|
|
||||||
* during SessionFactory.close().
|
|
||||||
*/
|
|
||||||
public void stop() {
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isMinimalPutsEnabledByDefault() {
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean afterInsert(Object key, Object value, Object version) throws CacheException {
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean update(Object key, Object value, Object currentVersion, Object previousVersion)
|
||||||
|
throws CacheException {
|
||||||
|
evict( key );
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,59 @@
|
||||||
|
/*
|
||||||
|
* Hibernate, Relational Persistence for Idiomatic Java
|
||||||
|
*
|
||||||
|
* Copyright (c) 2010-2011, Red Hat Inc. or third-party contributors as
|
||||||
|
* indicated by the @author tags or express copyright attribution
|
||||||
|
* statements applied by the authors. All third-party contributions are
|
||||||
|
* distributed under license by Red Hat Inc.
|
||||||
|
*
|
||||||
|
* This copyrighted material is made available to anyone wishing to use, modify,
|
||||||
|
* copy, or redistribute it subject to the terms and conditions of the GNU
|
||||||
|
* Lesser General Public License, as published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||||
|
* for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with this distribution; if not, write to:
|
||||||
|
* Free Software Foundation, Inc.
|
||||||
|
* 51 Franklin Street, Fifth Floor
|
||||||
|
* Boston, MA 02110-1301 USA
|
||||||
|
*/
|
||||||
|
package org.hibernate.testing.cache;
|
||||||
|
|
||||||
|
import org.jboss.logging.Logger;
|
||||||
|
|
||||||
|
import org.hibernate.cache.CacheException;
|
||||||
|
import org.hibernate.cache.spi.access.SoftLock;
|
||||||
|
import org.hibernate.internal.CoreMessageLogger;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Strong Liu
|
||||||
|
*/
|
||||||
|
class ReadOnlyCollectionRegionAccessStrategy extends BaseCollectionRegionAccessStrategy {
|
||||||
|
private static final CoreMessageLogger LOG = Logger.getMessageLogger(
|
||||||
|
CoreMessageLogger.class, ReadOnlyCollectionRegionAccessStrategy.class.getName()
|
||||||
|
);
|
||||||
|
|
||||||
|
ReadOnlyCollectionRegionAccessStrategy(CollectionRegionImpl region) {
|
||||||
|
super( region );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void unlockItem(Object key, SoftLock lock) throws CacheException {
|
||||||
|
LOG.invalidEditOfReadOnlyItem( key );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SoftLock lockItem(Object key, Object version) throws CacheException {
|
||||||
|
LOG.invalidEditOfReadOnlyItem( key );
|
||||||
|
throw new UnsupportedOperationException( "Can't write to a readonly object" );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void remove(Object key) throws CacheException {
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,86 @@
|
||||||
|
/*
|
||||||
|
* Hibernate, Relational Persistence for Idiomatic Java
|
||||||
|
*
|
||||||
|
* Copyright (c) 2010-2011, Red Hat Inc. or third-party contributors as
|
||||||
|
* indicated by the @author tags or express copyright attribution
|
||||||
|
* statements applied by the authors. All third-party contributions are
|
||||||
|
* distributed under license by Red Hat Inc.
|
||||||
|
*
|
||||||
|
* This copyrighted material is made available to anyone wishing to use, modify,
|
||||||
|
* copy, or redistribute it subject to the terms and conditions of the GNU
|
||||||
|
* Lesser General Public License, as published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||||
|
* for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with this distribution; if not, write to:
|
||||||
|
* Free Software Foundation, Inc.
|
||||||
|
* 51 Franklin Street, Fifth Floor
|
||||||
|
* Boston, MA 02110-1301 USA
|
||||||
|
*/
|
||||||
|
package org.hibernate.testing.cache;
|
||||||
|
|
||||||
|
import org.jboss.logging.Logger;
|
||||||
|
|
||||||
|
import org.hibernate.cache.CacheException;
|
||||||
|
import org.hibernate.cache.spi.access.SoftLock;
|
||||||
|
import org.hibernate.internal.CoreMessageLogger;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Strong Liu
|
||||||
|
*/
|
||||||
|
class ReadOnlyEntityRegionAccessStrategy extends BaseEntityRegionAccessStrategy {
|
||||||
|
private static final CoreMessageLogger LOG = Logger.getMessageLogger(
|
||||||
|
CoreMessageLogger.class, ReadOnlyEntityRegionAccessStrategy.class.getName()
|
||||||
|
);
|
||||||
|
|
||||||
|
ReadOnlyEntityRegionAccessStrategy(EntityRegionImpl region) {
|
||||||
|
super( region );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void remove(Object key) throws CacheException {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean insert(Object key, Object value, Object version) throws CacheException {
|
||||||
|
return false; //wait until tx complete, see afterInsert().
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean afterInsert(Object key, Object value, Object version) throws CacheException {
|
||||||
|
getInternalRegion().put( key, value ); //save into cache since the tx is completed
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void unlockItem(Object key, SoftLock lock) throws CacheException {
|
||||||
|
LOG.invalidEditOfReadOnlyItem( key );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SoftLock lockItem(Object key, Object version) throws CacheException {
|
||||||
|
LOG.invalidEditOfReadOnlyItem( key );
|
||||||
|
throw new UnsupportedOperationException( "Can't write to a readonly object" );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean update(Object key, Object value, Object currentVersion, Object previousVersion)
|
||||||
|
throws CacheException {
|
||||||
|
LOG.invalidEditOfReadOnlyItem( key );
|
||||||
|
throw new UnsupportedOperationException( "Can't write to a readonly object" );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean afterUpdate(Object key, Object value, Object currentVersion, Object previousVersion, SoftLock lock)
|
||||||
|
throws CacheException {
|
||||||
|
LOG.invalidEditOfReadOnlyItem( key );
|
||||||
|
throw new UnsupportedOperationException( "Can't write to a readonly object" );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
* Hibernate, Relational Persistence for Idiomatic Java
|
* Hibernate, Relational Persistence for Idiomatic Java
|
||||||
*
|
*
|
||||||
* Copyright (c) 2008-2011, Red Hat Inc. or third-party contributors as
|
* Copyright (c) 2010-2011, Red Hat Inc. or third-party contributors as
|
||||||
* indicated by the @author tags or express copyright attribution
|
* indicated by the @author tags or express copyright attribution
|
||||||
* statements applied by the authors. All third-party contributions are
|
* statements applied by the authors. All third-party contributions are
|
||||||
* distributed under license by Red Hat Inc.
|
* distributed under license by Red Hat Inc.
|
||||||
|
@ -21,19 +21,44 @@
|
||||||
* 51 Franklin Street, Fifth Floor
|
* 51 Franklin Street, Fifth Floor
|
||||||
* Boston, MA 02110-1301 USA
|
* Boston, MA 02110-1301 USA
|
||||||
*/
|
*/
|
||||||
package org.hibernate.cache.internal.bridge;
|
package org.hibernate.testing.cache;
|
||||||
|
|
||||||
import org.hibernate.cache.spi.Cache;
|
import java.util.Comparator;
|
||||||
import org.hibernate.cache.spi.QueryResultsRegion;
|
|
||||||
import org.hibernate.cfg.Settings;
|
import org.hibernate.cache.spi.CollectionRegion;
|
||||||
|
import org.hibernate.cache.spi.access.CollectionRegionAccessStrategy;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adapter specifically briding {@link org.hibernate.cache.spi.QueryResultsRegion} to {@link Cache}.
|
* @author Strong Liu
|
||||||
*
|
|
||||||
* @author Steve Ebersole
|
|
||||||
*/
|
*/
|
||||||
public class QueryResultsRegionAdapter extends BaseGeneralDataRegionAdapter implements QueryResultsRegion {
|
class ReadWriteCollectionRegionAccessStrategy extends AbstractReadWriteAccessStrategy
|
||||||
protected QueryResultsRegionAdapter(Cache underlyingCache, Settings settings) {
|
implements CollectionRegionAccessStrategy {
|
||||||
super( underlyingCache, settings );
|
|
||||||
|
private final CollectionRegionImpl region;
|
||||||
|
|
||||||
|
ReadWriteCollectionRegionAccessStrategy(CollectionRegionImpl region) {
|
||||||
|
this.region = region;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
Comparator getVersionComparator() {
|
||||||
|
return region.getCacheDataDescription().getVersionComparator();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected BaseGeneralDataRegion getInternalRegion() {
|
||||||
|
return region;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected boolean isDefaultMinimalPutOverride() {
|
||||||
|
return region.getSettings().isMinimalPutsEnabled();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CollectionRegion getRegion() {
|
||||||
|
return region;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
127
hibernate-testing/src/main/java/org/hibernate/testing/cache/ReadWriteEntityRegionAccessStrategy.java
vendored
Normal file
127
hibernate-testing/src/main/java/org/hibernate/testing/cache/ReadWriteEntityRegionAccessStrategy.java
vendored
Normal file
|
@ -0,0 +1,127 @@
|
||||||
|
/*
|
||||||
|
* Hibernate, Relational Persistence for Idiomatic Java
|
||||||
|
*
|
||||||
|
* Copyright (c) 2010-2011, Red Hat Inc. or third-party contributors as
|
||||||
|
* indicated by the @author tags or express copyright attribution
|
||||||
|
* statements applied by the authors. All third-party contributions are
|
||||||
|
* distributed under license by Red Hat Inc.
|
||||||
|
*
|
||||||
|
* This copyrighted material is made available to anyone wishing to use, modify,
|
||||||
|
* copy, or redistribute it subject to the terms and conditions of the GNU
|
||||||
|
* Lesser General Public License, as published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||||
|
* for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with this distribution; if not, write to:
|
||||||
|
* Free Software Foundation, Inc.
|
||||||
|
* 51 Franklin Street, Fifth Floor
|
||||||
|
* Boston, MA 02110-1301 USA
|
||||||
|
*/
|
||||||
|
package org.hibernate.testing.cache;
|
||||||
|
|
||||||
|
import java.util.Comparator;
|
||||||
|
|
||||||
|
import org.hibernate.cache.CacheException;
|
||||||
|
import org.hibernate.cache.spi.EntityRegion;
|
||||||
|
import org.hibernate.cache.spi.access.EntityRegionAccessStrategy;
|
||||||
|
import org.hibernate.cache.spi.access.SoftLock;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Strong Liu
|
||||||
|
*/
|
||||||
|
class ReadWriteEntityRegionAccessStrategy extends AbstractReadWriteAccessStrategy
|
||||||
|
implements EntityRegionAccessStrategy {
|
||||||
|
private final EntityRegionImpl region;
|
||||||
|
|
||||||
|
ReadWriteEntityRegionAccessStrategy(EntityRegionImpl region) {
|
||||||
|
this.region = region;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean insert(Object key, Object value, Object version) throws CacheException {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean update(Object key, Object value, Object currentVersion, Object previousVersion)
|
||||||
|
throws CacheException {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void evict(Object key) throws CacheException {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean afterInsert(Object key, Object value, Object version) throws CacheException {
|
||||||
|
|
||||||
|
try {
|
||||||
|
writeLock.lock();
|
||||||
|
Lockable item = (Lockable) region.get( key );
|
||||||
|
if ( item == null ) {
|
||||||
|
region.put( key, new Item( value, version, region.nextTimestamp() ) );
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
finally {
|
||||||
|
writeLock.unlock();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean afterUpdate(Object key, Object value, Object currentVersion, Object previousVersion, SoftLock lock)
|
||||||
|
throws CacheException {
|
||||||
|
try {
|
||||||
|
writeLock.lock();
|
||||||
|
Lockable item = (Lockable) region.get( key );
|
||||||
|
|
||||||
|
if ( item != null && item.isUnlockable( lock ) ) {
|
||||||
|
Lock lockItem = (Lock) item;
|
||||||
|
if ( lockItem.wasLockedConcurrently() ) {
|
||||||
|
decrementLock( key, lockItem );
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
region.put( key, new Item( value, currentVersion, region.nextTimestamp() ) );
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
handleLockExpiry( key, item );
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
finally {
|
||||||
|
writeLock.unlock();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected BaseGeneralDataRegion getInternalRegion() {
|
||||||
|
return region;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected boolean isDefaultMinimalPutOverride() {
|
||||||
|
return region.getSettings().isMinimalPutsEnabled();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
Comparator getVersionComparator() {
|
||||||
|
return region.getCacheDataDescription().getVersionComparator();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public EntityRegion getRegion() {
|
||||||
|
return region;
|
||||||
|
}
|
||||||
|
}
|
|
@ -37,7 +37,6 @@ import java.util.Properties;
|
||||||
import org.hibernate.HibernateException;
|
import org.hibernate.HibernateException;
|
||||||
import org.hibernate.Interceptor;
|
import org.hibernate.Interceptor;
|
||||||
import org.hibernate.Session;
|
import org.hibernate.Session;
|
||||||
import org.hibernate.cache.internal.HashtableCacheProvider;
|
|
||||||
import org.hibernate.cfg.AvailableSettings;
|
import org.hibernate.cfg.AvailableSettings;
|
||||||
import org.hibernate.cfg.Configuration;
|
import org.hibernate.cfg.Configuration;
|
||||||
import org.hibernate.cfg.Environment;
|
import org.hibernate.cfg.Environment;
|
||||||
|
@ -62,6 +61,7 @@ import org.hibernate.testing.BeforeClassOnce;
|
||||||
import org.hibernate.testing.OnExpectedFailure;
|
import org.hibernate.testing.OnExpectedFailure;
|
||||||
import org.hibernate.testing.OnFailure;
|
import org.hibernate.testing.OnFailure;
|
||||||
import org.hibernate.testing.SkipLog;
|
import org.hibernate.testing.SkipLog;
|
||||||
|
import org.hibernate.testing.cache.CachingRegionFactory;
|
||||||
|
|
||||||
import static org.junit.Assert.fail;
|
import static org.junit.Assert.fail;
|
||||||
|
|
||||||
|
@ -130,7 +130,7 @@ public abstract class BaseCoreFunctionalTestCase extends BaseUnitTestCase {
|
||||||
|
|
||||||
protected Configuration constructConfiguration() {
|
protected Configuration constructConfiguration() {
|
||||||
Configuration configuration = new Configuration()
|
Configuration configuration = new Configuration()
|
||||||
.setProperty( Environment.CACHE_PROVIDER, HashtableCacheProvider.class.getName() );
|
.setProperty(Environment.CACHE_REGION_FACTORY, CachingRegionFactory.class.getName() );
|
||||||
configuration.setProperty( AvailableSettings.USE_NEW_ID_GENERATOR_MAPPINGS, "true" );
|
configuration.setProperty( AvailableSettings.USE_NEW_ID_GENERATOR_MAPPINGS, "true" );
|
||||||
if ( createSchema() ) {
|
if ( createSchema() ) {
|
||||||
configuration.setProperty( Environment.HBM2DDL_AUTO, "create-drop" );
|
configuration.setProperty( Environment.HBM2DDL_AUTO, "create-drop" );
|
||||||
|
|
Loading…
Reference in New Issue