HHH-6297 remove legacy cache api

This commit is contained in:
Strong Liu 2011-06-09 03:53:04 +08:00
parent ad180ff95a
commit 92ad3eed80
67 changed files with 1958 additions and 3990 deletions

View File

@ -750,9 +750,9 @@ Customer customer = (Customer) session.get( Customer.class, customerId );
<tbody>
<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>
@ -764,7 +764,7 @@ Customer customer = (Customer) session.get( Customer.class, customerId );
<row>
<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>
@ -773,7 +773,7 @@ Customer customer = (Customer) session.get( Customer.class, customerId );
<entry>yes</entry>
</row>
<row>
<!-- <row>
<entry>OSCache</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 (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>
</row>
</tbody>
@ -1114,7 +1125,7 @@ public SortedSet&lt;Ticket&gt; getTickets() {
<tbody>
<row>
<entry>Hashtable (not intended for production use)</entry>
<entry>ConcurrentHashMap (not intended for production use)</entry>
<entry>yes</entry>
@ -1134,10 +1145,10 @@ public SortedSet&lt;Ticket&gt; getTickets() {
<entry>yes</entry>
<entry></entry>
<entry>yes</entry>
</row>
<row>
<!-- <row>
<entry>OSCache</entry>
<entry>yes</entry>
@ -1182,6 +1193,17 @@ public SortedSet&lt;Ticket&gt; getTickets() {
<entry></entry>
<entry>yes</entry>
</row> -->
<row>
<entry>Infinispan</entry>
<entry>yes</entry>
<entry></entry>
<entry></entry>
<entry>yes</entry>
</row>
</tbody>

View File

@ -492,13 +492,11 @@ hibernate.cache.region_prefix hibernate.test
## choose a cache implementation
#hibernate.cache.provider_class org.hibernate.cache.EhCacheProvider
#hibernate.cache.provider_class org.hibernate.cache.EmptyCacheProvider
hibernate.cache.provider_class org.hibernate.cache.internal.HashtableCacheProvider
#hibernate.cache.provider_class org.hibernate.cache.TreeCacheProvider
#hibernate.cache.provider_class org.hibernate.cache.OSCacheProvider
#hibernate.cache.provider_class org.hibernate.cache.SwarmCacheProvider
#hibernate.cache.region.factory_class org.hibernate.cache.infinispan.InfinispanRegionFactory
#hibernate.cache.region.factory_class org.hibernate.cache.infinispan.JndiInfinispanRegionFactory
#hibernate.cache.region.factory_class org.hibernate.cache.internal.EhCacheRegionFactory
#hibernate.cache.region.factory_class org.hibernate.cache.internal.SingletonEhCacheRegionFactory
hibernate.cache.region.factory_class org.hibernate.cache.internal.NoCachingRegionFactory
## choose a custom query cache implementation

View File

@ -451,12 +451,11 @@ hibernate.cache.region_prefix hibernate.test
## choose a cache implementation
#hibernate.cache.provider_class org.hibernate.cache.EhCacheProvider
#hibernate.cache.provider_class org.hibernate.cache.EmptyCacheProvider
hibernate.cache.provider_class org.hibernate.cache.HashtableCacheProvider
#hibernate.cache.provider_class org.hibernate.cache.TreeCacheProvider
#hibernate.cache.provider_class org.hibernate.cache.OSCacheProvider
#hibernate.cache.provider_class org.hibernate.cache.SwarmCacheProvider
#hibernate.cache.region.factory_class org.hibernate.cache.infinispan.InfinispanRegionFactory
#hibernate.cache.region.factory_class org.hibernate.cache.infinispan.JndiInfinispanRegionFactory
#hibernate.cache.region.factory_class org.hibernate.cache.internal.EhCacheRegionFactory
#hibernate.cache.region.factory_class org.hibernate.cache.internal.SingletonEhCacheRegionFactory
#hibernate.cache.region.factory_class org.hibernate.cache.internal.NoCachingRegionFactory
## choose a custom query cache implementation

View File

@ -25,7 +25,10 @@ package org.hibernate;
import java.util.Map;
import org.jboss.logging.Logger;
import org.hibernate.cfg.Environment;
import org.hibernate.internal.CoreMessageLogger;
/**
* Describes the methods for multi-tenancy understood by Hibernate.
@ -33,6 +36,7 @@ import org.hibernate.cfg.Environment;
* @author Steve Ebersole
*/
public enum MultiTenancyStrategy {
/**
* Multi-tenancy implemented by use of discriminator columns.
*/
@ -49,7 +53,10 @@ public enum MultiTenancyStrategy {
* No multi-tenancy
*/
NONE;
private static final CoreMessageLogger LOG = Logger.getMessageLogger(
CoreMessageLogger.class,
MultiTenancyStrategy.class.getName()
);
public static MultiTenancyStrategy determineMultiTenancyStrategy(Map properties) {
final Object strategy = properties.get( Environment.MULTI_TENANT );
if ( strategy == null ) {
@ -61,20 +68,11 @@ public enum MultiTenancyStrategy {
}
final String strategyName = strategy.toString();
if ( MultiTenancyStrategy.DISCRIMINATOR.name().equals( strategyName ) ) {
return MultiTenancyStrategy.DISCRIMINATOR;
try {
return MultiTenancyStrategy.valueOf( strategyName.toUpperCase() );
}
else if ( MultiTenancyStrategy.SCHEMA.name().equals( strategyName ) ) {
return MultiTenancyStrategy.SCHEMA;
}
else if ( MultiTenancyStrategy.DATABASE.name().equals( strategyName ) ) {
return MultiTenancyStrategy.DATABASE;
}
else if ( MultiTenancyStrategy.NONE.name().equals( strategyName ) ) {
return MultiTenancyStrategy.NONE;
}
else {
// todo log?
catch ( RuntimeException e ) {
LOG.warn( "Unknown multi tenancy strategy [ " +strategyName +" ], using MultiTenancyStrategy.NONE." );
return MultiTenancyStrategy.NONE;
}
}

View File

@ -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 + ')';
}
}

View File

@ -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;
}
}

View File

@ -23,29 +23,28 @@
*/
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
* necessarily strictly increasing, but usually are.
*/
public final class Timestamper {
private static short counter = 0;
private static long time;
private static final int BIN_DIGITS = 12;
public static final short ONE_MS = 1<<BIN_DIGITS;
private static final AtomicLong VALUE = new AtomicLong();
public static long next() {
synchronized(Timestamper.class) {
long newTime = System.currentTimeMillis() << BIN_DIGITS;
if (time<newTime) {
time = newTime;
counter = 0;
}
else if (counter < ONE_MS - 1 ) {
counter++;
}
while (true) {
long base = System.currentTimeMillis() << BIN_DIGITS;
long maxValue = base + ONE_MS - 1;
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;
}
}
}
}
private Timestamper() {

View File

@ -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();
}
}

View File

@ -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 );
}
}

View File

@ -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();
}
}

View File

@ -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 );
}
}

View File

@ -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 );
}
}

View File

@ -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 );
}
}

View File

@ -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;
}
}

View File

@ -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();
}

View File

@ -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();
}

View File

@ -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();
}

View File

@ -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)";
}
}

View File

@ -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);
}

View File

@ -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)";
}
}

View File

@ -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)";
}
}

View File

@ -38,12 +38,7 @@ import org.hibernate.service.Service;
* <li>MyRegionFactoryImpl()</li>
* </ul>
* 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 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}.
* {@link #start(Settings, Properties)} being called.
*
* @author Steve Ebersole
*/

View File

@ -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)";
}
}

View File

@ -104,37 +104,4 @@ public interface EntityRegionAccessStrategy extends RegionAccessStrategy{
* @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;
/**
* 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;
}

View File

@ -288,13 +288,6 @@ public interface AvailableSettings {
@Deprecated
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
*/

View File

@ -75,11 +75,6 @@ import org.hibernate.internal.util.config.ConfigurationHelper;
* <td>classname of <tt>org.hibernate.dialect.Dialect</tt> subclass</td>
* </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>classname of <tt>org.hibernate.service.jdbc.connections.spi.ConnectionProvider</tt>
* subclass (if not specified hueristics are used)</td>

View File

@ -55,7 +55,7 @@ public abstract class ExternalSessionFactoryConfig {
private String querySubstitutions;
private String showSqlEnabled;
private String commentsEnabled;
private String cacheProviderClass;
private String cacheRegionFactory;
private String cacheProviderConfig;
private String cacheRegionPrefix;
private String secondLevelCacheEnabled;
@ -209,12 +209,12 @@ public abstract class ExternalSessionFactoryConfig {
this.secondLevelCacheEnabled = secondLevelCacheEnabled;
}
public final String getCacheProviderClass() {
return cacheProviderClass;
public final String getCacheRegionFactory() {
return cacheRegionFactory;
}
public final void setCacheProviderClass(String cacheProviderClass) {
this.cacheProviderClass = cacheProviderClass;
public final void setCacheRegionFactory(String cacheRegionFactory) {
this.cacheRegionFactory = cacheRegionFactory;
}
public String getCacheProviderConfig() {
@ -287,7 +287,7 @@ public abstract class ExternalSessionFactoryConfig {
setUnlessNull( props, Environment.QUERY_SUBSTITUTIONS, querySubstitutions );
setUnlessNull( props, Environment.SHOW_SQL, showSqlEnabled );
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_REGION_PREFIX, cacheRegionPrefix );
setUnlessNull( props, Environment.USE_MINIMAL_PUTS, minimalPutsEnabled );

View File

@ -34,9 +34,9 @@ import org.hibernate.EntityMode;
import org.hibernate.HibernateException;
import org.hibernate.MultiTenancyStrategy;
import org.hibernate.cache.internal.NoCachingRegionFactory;
import org.hibernate.cache.internal.StandardQueryCacheFactory;
import org.hibernate.cache.spi.QueryCacheFactory;
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.JdbcServices;
import org.hibernate.engine.transaction.spi.TransactionFactory;
@ -305,7 +305,7 @@ public class SettingsFactory implements Serializable {
protected QueryCacheFactory createQueryCacheFactory(Properties properties, ServiceRegistry serviceRegistry) {
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 );
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(
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 ) {
if ( regionFactoryClassName == null || !cachingEnabled) {
regionFactoryClassName = DEF_CACHE_REG_FACTORY;
}
LOG.debugf( "Cache region factory : %s", regionFactoryClassName );
@ -355,56 +348,49 @@ public class SettingsFactory implements Serializable {
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) {
String className = ConfigurationHelper.getString(
Environment.QUERY_TRANSLATOR, properties, "org.hibernate.hql.internal.ast.ASTQueryTranslatorFactory"
);
LOG.debugf( "Query translator: %s", className );
LOG.debugf( "Query translator: %s", className );
try {
return (QueryTranslatorFactory) serviceRegistry.getService( ClassLoaderService.class )
.classForName( className )
.newInstance();
}
catch (Exception e) {
catch ( Exception 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 );
}
}
}

View File

@ -222,11 +222,11 @@ public interface HibernateServiceMBean {
/**
* Get the second-level cache provider class name
*/
public String getCacheProviderClass();
public String getCacheRegionFactory();
/**
* 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
* provider's specific configuration resource.

View File

@ -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" ) );
}
}

View File

@ -29,7 +29,6 @@ import java.sql.SQLException;
import org.hibernate.HibernateException;
import org.hibernate.MultiTenancyStrategy;
import org.hibernate.Session;
import org.hibernate.cache.internal.HashtableCacheProvider;
import org.hibernate.cfg.Configuration;
import org.hibernate.cfg.Environment;
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.MultiTenantConnectionProvider;
import org.hibernate.service.spi.ServiceRegistryImplementor;
import org.hibernate.testing.cache.CachingRegionFactory;
import org.hibernate.tool.hbm2ddl.ConnectionHelper;
import org.hibernate.tool.hbm2ddl.SchemaExport;
@ -86,7 +86,7 @@ public class SchemaBasedMultiTenancyTest extends BaseUnitTestCase {
Configuration cfg = new Configuration();
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.addAnnotatedClass( Customer.class );

View File

@ -33,4 +33,4 @@ hibernate.show_sql true
hibernate.max_fetch_depth 5
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

View File

@ -7,4 +7,4 @@ log4j.appender.stdout.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n
log4j.rootLogger=info, stdout
log4j.logger.org.hibernate.tool.hbm2ddl=debug
log4j.logger.org.hibernate.testing.cache=debug

View File

@ -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() + ')';
}
}

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -1,31 +1,31 @@
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.Environment;
import java.util.Map;
import net.sf.ehcache.hibernate.EhCacheRegionFactory;
/**
* @author Alex Snaps
*/
public class EhCacheRegionTest extends EhCacheTest {
@Override
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" );
}
@Override
protected Map getMapFromCacheEntry(final Object entry) {
final Map map;
if ( entry instanceof Item ) {
map = (Map) ( (Item) entry ).getValue();
}
else {
// if ( entry instanceof Item ) {
// map = (Map) ( (Item) entry ).getValue();
// }
// else {
map = (Map) entry;
}
// }
return map;
}
}

View File

@ -26,8 +26,6 @@ package org.hibernate.test.cache.ehcache;
import java.util.Map;
import org.hibernate.Session;
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.Environment;
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() );
Long cachedVersionValue;
if ( entry instanceof ReadWriteCache.Lock ) {
//FIXME don't know what to test here
cachedVersionValue = Long.valueOf( ((ReadWriteCache.Lock) entry).getUnlockTimestamp() );
} else if(entry.getClass().getName().equals("net.sf.ehcache.hibernate.strategy.AbstractReadWriteEhcacheAccessStrategy$Lock")) {
// if ( entry instanceof ReadWriteCache.Lock ) {
// //FIXME don't know what to test here
// cachedVersionValue = Long.valueOf( ((ReadWriteCache.Lock) entry).getUnlockTimestamp() );
// } else
if(entry.getClass().getName().equals("net.sf.ehcache.hibernate.strategy.AbstractReadWriteEhcacheAccessStrategy$Lock")) {
//FIXME don't know what to test here
} else {
cachedVersionValue = ( Long ) getMapFromCacheEntry(entry).get( "_version" );

View File

@ -16,7 +16,7 @@
<property name="hibernate.max_fetch_depth">3</property>
<property name="hibernate.hbm2ddl.auto">create-drop</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.Cat"/>
<mapping class="org.hibernate.ejb.test.Kitten"/>

View File

@ -14,7 +14,7 @@
<property name="hibernate.connection.password" value="@jdbc.pass@"/>
<property name="hibernate.connection.url" value="@jdbc.url@"/>
<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>
</persistence-unit>
</persistence>

View File

@ -13,7 +13,7 @@
<property name="hibernate.connection.password" value="@jdbc.pass@"/>
<property name="hibernate.connection.url" value="@jdbc.url@"/>
<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>
</persistence-unit>
</persistence>

View File

@ -13,7 +13,7 @@
<property name="hibernate.connection.password" value="@jdbc.pass@"/>
<property name="hibernate.connection.url" value="@jdbc.url@"/>
<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"/>
</properties>
</persistence-unit>

View File

@ -26,7 +26,7 @@
<property name="hibernate.max_fetch_depth" value="3"/>
<property name="hibernate.hbm2ddl.auto" value="create-drop"/>
<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"/>
<!-- test naming strategy and fall back to element content -->
<!-- property name="hibernate.ejb.naming_strategy">org.hibernate.ejb.test.MyNamingStrategy</property -->

View File

@ -12,7 +12,7 @@
<property name="hibernate.connection.password" value="@jdbc.pass@"/>
<property name="hibernate.connection.url" value="@jdbc.url@"/>
<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>
</persistence-unit>
</persistence>

View File

@ -8,7 +8,7 @@
<properties>
<property name="hibernate.dialect" value="@db.dialect@"/>
<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>
</persistence-unit>
</persistence>

View File

@ -12,7 +12,7 @@
<property name="hibernate.connection.password" value="@jdbc.pass@"/>
<property name="hibernate.connection.url" value="@jdbc.url@"/>
<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>
</persistence-unit>
</persistence>

View File

@ -13,7 +13,7 @@
<property name="hibernate.connection.password" value="@jdbc.pass@"/>
<property name="hibernate.connection.url" value="@jdbc.url@"/>
<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>
</persistence-unit>
</persistence>

View File

@ -33,6 +33,6 @@ hibernate.show_sql true
hibernate.max_fetch_depth 5
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

View File

@ -16,7 +16,7 @@
<property name="hibernate.max_fetch_depth">3</property>
<property name="hibernate.hbm2ddl.auto">create-drop</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.Cat"/>
<mapping class="org.hibernate.ejb.test.Kitten"/>

View File

@ -1,7 +1,7 @@
package org.hibernate.envers.test.integration.cache;
import org.hibernate.MappingException;
import org.hibernate.cache.internal.EhCacheProvider;
import org.hibernate.cache.internal.EhCacheRegionFactory;
import org.hibernate.cfg.Environment;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.envers.RevisionType;
@ -26,7 +26,7 @@ public class HibernateSecLvlQueryCache extends AbstractSessionTest {
config.addAnnotatedClass(StrTestEntity.class);
config.setProperty(Environment.USE_SECOND_LEVEL_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");
}

View 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();
}
}
}

View File

@ -1,7 +1,7 @@
/*
* 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
* statements applied by the authors. All third-party contributions are
* distributed under license by Red Hat Inc.
@ -21,37 +21,34 @@
* 51 Franklin Street, Fifth Floor
* 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.Cache;
import org.hibernate.cache.spi.CollectionRegion;
import org.hibernate.cache.spi.GeneralDataRegion;
import org.hibernate.cfg.Settings;
import org.hibernate.cache.spi.access.CollectionRegionAccessStrategy;
/**
* {@inheritDoc}
*
* @author Steve Ebersole
* @author Strong Liu
*/
public abstract class BaseGeneralDataRegionAdapter extends BaseRegionAdapter implements GeneralDataRegion {
class BaseCollectionRegionAccessStrategy extends BaseRegionAccessStrategy implements CollectionRegionAccessStrategy {
private final CollectionRegionImpl region;
protected BaseGeneralDataRegionAdapter(Cache underlyingCache, Settings settings) {
super( underlyingCache, settings );
@Override
protected BaseGeneralDataRegion getInternalRegion() {
return region;
}
public Object get(Object key) throws CacheException {
return underlyingCache.get( key );
@Override
protected boolean isDefaultMinimalPutOverride() {
return region.getSettings().isMinimalPutsEnabled();
}
public void put(Object key, Object value) throws CacheException {
underlyingCache.put( key, value );
@Override
public CollectionRegion getRegion() {
return region;
}
public void evict(Object key) throws CacheException {
underlyingCache.remove( key );
}
public void evictAll() throws CacheException {
underlyingCache.clear();
BaseCollectionRegionAccessStrategy(CollectionRegionImpl region) {
this.region = region;
}
}

View 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();
}
}

View 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();
}
}

View File

@ -1,7 +1,7 @@
/*
* 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
* statements applied by the authors. All third-party contributions are
* distributed under license by Red Hat Inc.
@ -21,67 +21,72 @@
* 51 Franklin Street, Fifth Floor
* 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.concurrent.ConcurrentHashMap;
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.cfg.Settings;
/**
* Basic adapter bridging between {@link Region} and {@link Cache}.
*
* @author Steve Ebersole
* @author Strong Liu
*/
public abstract class BaseRegionAdapter implements Region {
protected final Cache underlyingCache;
protected final Settings settings;
class BaseRegion implements Region {
protected final Map cache = new ConcurrentHashMap();
private final String name;
protected BaseRegionAdapter(Cache underlyingCache, Settings settings) {
this.underlyingCache = underlyingCache;
this.settings = settings;
}
public String getName() {
return underlyingCache.getRegionName();
}
public void clear() throws CacheException {
underlyingCache.clear();
}
public void destroy() throws CacheException {
underlyingCache.destroy();
BaseRegion(String name) {
this.name = name;
}
@Override
public boolean contains(Object key) {
// safer to utilize the toMap() as oposed to say get(key) != null
return underlyingCache.toMap().containsKey( key );
return key != null ? cache.containsKey( key ) : false;
}
@Override
public String getName() {
return name;
}
@Override
public void destroy() throws CacheException {
cache.clear();
}
@Override
public long getSizeInMemory() {
return underlyingCache.getSizeInMemory();
return -1;
}
@Override
public long getElementCountInMemory() {
return underlyingCache.getElementCountInMemory();
return cache.size();
}
@Override
public long getElementCountOnDisk() {
return underlyingCache.getElementCountOnDisk();
return 0;
}
@Override
public Map toMap() {
return underlyingCache.toMap();
return Collections.unmodifiableMap( cache );
}
@Override
public long nextTimestamp() {
return underlyingCache.nextTimestamp();
return Timestamper.next();
}
@Override
public int getTimeout() {
return underlyingCache.getTimeout();
return Timestamper.ONE_MS * 60000;
}
}

View 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();
}
}

View File

@ -1,7 +1,7 @@
/*
* 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
* statements applied by the authors. All third-party contributions are
* distributed under license by Red Hat Inc.
@ -21,35 +21,30 @@
* 51 Franklin Street, Fifth Floor
* 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.TransactionAwareCache;
import org.hibernate.cache.spi.TransactionalDataRegion;
import org.hibernate.cfg.Settings;
/**
* {@inheritDoc}
*
* @author Steve Ebersole
* @author Strong Liu
*/
public abstract class BaseTransactionalDataRegionAdapter
extends BaseRegionAdapter
implements TransactionalDataRegion {
class BaseTransactionalDataRegion extends BaseGeneralDataRegion implements TransactionalDataRegion {
private final CacheDataDescription metadata;
protected final CacheDataDescription metadata;
protected BaseTransactionalDataRegionAdapter(Cache underlyingCache, Settings settings, CacheDataDescription metadata) {
super( underlyingCache, settings );
BaseTransactionalDataRegion(String name, CacheDataDescription metadata) {
super( name );
this.metadata = metadata;
}
public boolean isTransactionAware() {
return underlyingCache instanceof TransactionAwareCache;
}
@Override
public CacheDataDescription getCacheDataDescription() {
return metadata;
}
@Override
public boolean isTransactionAware() {
return false;
}
}

View 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 );
}
}
}

View 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 + "]" );
}
}
}

View 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 + "]" );
}
}
}

View File

@ -1,7 +1,7 @@
/*
* 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
* statements applied by the authors. All third-party contributions are
* distributed under license by Red Hat Inc.
@ -21,30 +21,28 @@
* 51 Franklin Street, Fifth Floor
* 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.spi.OptimisticCacheSource;
import org.hibernate.cache.CacheException;
import org.hibernate.cache.spi.access.SoftLock;
import org.hibernate.internal.CoreMessageLogger;
/**
* {@inheritDoc}
*
* @author Steve Ebersole
*/
public class OptimisticCacheSourceAdapter implements OptimisticCacheSource {
private final CacheDataDescription dataDescription;
* @author Strong Liu
*/
class NonstrictReadWriteCollectionRegionAccessStrategy extends BaseCollectionRegionAccessStrategy {
private static final CoreMessageLogger LOG = Logger.getMessageLogger(
CoreMessageLogger.class, NonstrictReadWriteCollectionRegionAccessStrategy.class.getName()
);
public OptimisticCacheSourceAdapter(CacheDataDescription dataDescription) {
this.dataDescription = dataDescription;
NonstrictReadWriteCollectionRegionAccessStrategy(CollectionRegionImpl region) {
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();
}
}

View File

@ -1,7 +1,7 @@
/*
* 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
* statements applied by the authors. All third-party contributions are
* distributed under license by Red Hat Inc.
@ -21,48 +21,41 @@
* 51 Franklin Street, Fifth Floor
* 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.spi.Cache;
import org.hibernate.cache.spi.CacheProvider;
import org.hibernate.cache.spi.access.SoftLock;
import org.hibernate.internal.CoreMessageLogger;
/**
* A simple in-memory Hashtable-based cache impl.
*
* @author Gavin King
* @author Strong Liu
*/
public class HashtableCacheProvider implements CacheProvider {
public Cache buildCache(String regionName, Properties properties) throws CacheException {
return new HashtableCache( regionName );
class NonstrictReadWriteEntityRegionAccessStrategy extends BaseEntityRegionAccessStrategy {
NonstrictReadWriteEntityRegionAccessStrategy(EntityRegionImpl region) {
super( region );
}
public long nextTimestamp() {
return Timestamper.next();
@Override
public void unlockItem(Object key, SoftLock lock) throws CacheException {
evict( key );
}
/**
* 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() {
@Override
public boolean insert(Object key, Object value, Object version) throws CacheException {
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;
}
}

View File

@ -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 {
}
}

View File

@ -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" );
}
}

View File

@ -1,7 +1,7 @@
/*
* 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
* statements applied by the authors. All third-party contributions are
* distributed under license by Red Hat Inc.
@ -21,19 +21,44 @@
* 51 Franklin Street, Fifth Floor
* 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.QueryResultsRegion;
import org.hibernate.cfg.Settings;
import java.util.Comparator;
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 Steve Ebersole
* @author Strong Liu
*/
public class QueryResultsRegionAdapter extends BaseGeneralDataRegionAdapter implements QueryResultsRegion {
protected QueryResultsRegionAdapter(Cache underlyingCache, Settings settings) {
super( underlyingCache, settings );
class ReadWriteCollectionRegionAccessStrategy extends AbstractReadWriteAccessStrategy
implements CollectionRegionAccessStrategy {
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;
}
}

View 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;
}
}

View File

@ -37,7 +37,6 @@ import java.util.Properties;
import org.hibernate.HibernateException;
import org.hibernate.Interceptor;
import org.hibernate.Session;
import org.hibernate.cache.internal.HashtableCacheProvider;
import org.hibernate.cfg.AvailableSettings;
import org.hibernate.cfg.Configuration;
import org.hibernate.cfg.Environment;
@ -62,6 +61,7 @@ import org.hibernate.testing.BeforeClassOnce;
import org.hibernate.testing.OnExpectedFailure;
import org.hibernate.testing.OnFailure;
import org.hibernate.testing.SkipLog;
import org.hibernate.testing.cache.CachingRegionFactory;
import static org.junit.Assert.fail;
@ -130,7 +130,7 @@ public abstract class BaseCoreFunctionalTestCase extends BaseUnitTestCase {
protected Configuration constructConfiguration() {
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" );
if ( createSchema() ) {
configuration.setProperty( Environment.HBM2DDL_AUTO, "create-drop" );