mirror of
https://github.com/hibernate/hibernate-orm
synced 2025-03-03 00:09:19 +00:00
Added RegionFactory to the default Ehcache hibernate integration. Plus tests. Upgraded Ehcache to 2.4.1
This commit is contained in:
parent
57b60e30a7
commit
9fe7913003
@ -48,8 +48,8 @@
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>net.sf.ehcache</groupId>
|
||||
<artifactId>ehcache</artifactId>
|
||||
<version>1.5.0</version>
|
||||
<artifactId>ehcache-core</artifactId>
|
||||
<version>2.4.1</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>${project.groupId}</groupId>
|
||||
|
56
hibernate-ehcache/src/main/java/org/hibernate/cache/DelegatingRegionFactory.java
vendored
Normal file
56
hibernate-ehcache/src/main/java/org/hibernate/cache/DelegatingRegionFactory.java
vendored
Normal file
@ -0,0 +1,56 @@
|
||||
package org.hibernate.cache;
|
||||
|
||||
import org.hibernate.cache.access.AccessType;
|
||||
import org.hibernate.cfg.Settings;
|
||||
|
||||
import java.util.Properties;
|
||||
|
||||
/**
|
||||
* @author Alex Snaps
|
||||
*/
|
||||
public class DelegatingRegionFactory implements RegionFactory {
|
||||
|
||||
private final RegionFactory regionFactory;
|
||||
|
||||
DelegatingRegionFactory(final RegionFactory regionFactory) {
|
||||
this.regionFactory = regionFactory;
|
||||
}
|
||||
|
||||
public final void start(final Settings settings, final Properties properties) throws CacheException {
|
||||
regionFactory.start(settings, properties);
|
||||
}
|
||||
|
||||
public final void stop() {
|
||||
regionFactory.stop();
|
||||
}
|
||||
|
||||
public final boolean isMinimalPutsEnabledByDefault() {
|
||||
return regionFactory.isMinimalPutsEnabledByDefault();
|
||||
}
|
||||
|
||||
public final AccessType getDefaultAccessType() {
|
||||
return regionFactory.getDefaultAccessType();
|
||||
}
|
||||
|
||||
public final long nextTimestamp() {
|
||||
return regionFactory.nextTimestamp();
|
||||
}
|
||||
|
||||
public final EntityRegion buildEntityRegion(final String regionName, final Properties properties,
|
||||
final CacheDataDescription metadata) throws CacheException {
|
||||
return regionFactory.buildEntityRegion(regionName, properties, metadata);
|
||||
}
|
||||
|
||||
public final CollectionRegion buildCollectionRegion(final String regionName, final Properties properties,
|
||||
final CacheDataDescription metadata) throws CacheException {
|
||||
return regionFactory.buildCollectionRegion(regionName, properties, metadata);
|
||||
}
|
||||
|
||||
public final QueryResultsRegion buildQueryResultsRegion(final String regionName, final Properties properties) throws CacheException {
|
||||
return regionFactory.buildQueryResultsRegion(regionName, properties);
|
||||
}
|
||||
|
||||
public final TimestampsRegion buildTimestampsRegion(final String regionName, final Properties properties) throws CacheException {
|
||||
return regionFactory.buildTimestampsRegion(regionName, properties);
|
||||
}
|
||||
}
|
13
hibernate-ehcache/src/main/java/org/hibernate/cache/EhCacheRegionFactory.java
vendored
Normal file
13
hibernate-ehcache/src/main/java/org/hibernate/cache/EhCacheRegionFactory.java
vendored
Normal file
@ -0,0 +1,13 @@
|
||||
package org.hibernate.cache;
|
||||
|
||||
import java.util.Properties;
|
||||
|
||||
/**
|
||||
* @author Alex Snaps
|
||||
*/
|
||||
public class EhCacheRegionFactory extends DelegatingRegionFactory {
|
||||
|
||||
public EhCacheRegionFactory(final Properties properties) {
|
||||
super(new net.sf.ehcache.hibernate.EhCacheRegionFactory(properties));
|
||||
}
|
||||
}
|
12
hibernate-ehcache/src/main/java/org/hibernate/cache/SingletonEhCacheRegionFactory.java
vendored
Normal file
12
hibernate-ehcache/src/main/java/org/hibernate/cache/SingletonEhCacheRegionFactory.java
vendored
Normal file
@ -0,0 +1,12 @@
|
||||
package org.hibernate.cache;
|
||||
|
||||
import java.util.Properties;
|
||||
|
||||
/**
|
||||
* @author Alex Snaps
|
||||
*/
|
||||
public class SingletonEhCacheRegionFactory extends DelegatingRegionFactory {
|
||||
public SingletonEhCacheRegionFactory(Properties properties) {
|
||||
super(new net.sf.ehcache.hibernate.SingletonEhCacheRegionFactory(properties));
|
||||
}
|
||||
}
|
@ -1,64 +1,64 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
import junit.framework.Test;
|
||||
|
||||
import org.hibernate.cfg.Environment;
|
||||
import org.hibernate.testing.junit.functional.FunctionalTestClassTestSuite;
|
||||
import org.hibernate.testing.cache.BaseCacheProviderTestCase;
|
||||
|
||||
/**
|
||||
* @author Emmanuel Bernard
|
||||
*/
|
||||
public class EhCacheTest extends BaseCacheProviderTestCase {
|
||||
public EhCacheTest(String x) {
|
||||
super( x );
|
||||
}
|
||||
|
||||
public static Test suite() {
|
||||
return new FunctionalTestClassTestSuite( EhCacheTest.class );
|
||||
}
|
||||
|
||||
public String getCacheConcurrencyStrategy() {
|
||||
return "read-write";
|
||||
}
|
||||
|
||||
protected Class getCacheProvider() {
|
||||
return EhCacheProvider.class;
|
||||
}
|
||||
|
||||
protected String getConfigResourceKey() {
|
||||
return Environment.CACHE_PROVIDER_CONFIG;
|
||||
}
|
||||
|
||||
protected String getConfigResourceLocation() {
|
||||
return "ehcache.xml";
|
||||
}
|
||||
|
||||
protected boolean useTransactionManager() {
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
/*
|
||||
* 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;
|
||||
|
||||
import junit.framework.Test;
|
||||
|
||||
import org.hibernate.cfg.Environment;
|
||||
import org.hibernate.testing.junit.functional.FunctionalTestClassTestSuite;
|
||||
import org.hibernate.testing.cache.BaseCacheProviderTestCase;
|
||||
|
||||
/**
|
||||
* @author Emmanuel Bernard
|
||||
*/
|
||||
public class EhCacheProviderTest extends BaseCacheProviderTestCase {
|
||||
public EhCacheProviderTest(String x) {
|
||||
super(x);
|
||||
}
|
||||
|
||||
public static Test suite() {
|
||||
return new FunctionalTestClassTestSuite(EhCacheProviderTest.class);
|
||||
}
|
||||
|
||||
public String getCacheConcurrencyStrategy() {
|
||||
return "read-write";
|
||||
}
|
||||
|
||||
protected Class getCacheProvider() {
|
||||
return EhCacheProvider.class;
|
||||
}
|
||||
|
||||
protected String getConfigResourceKey() {
|
||||
return Environment.CACHE_PROVIDER_CONFIG;
|
||||
}
|
||||
|
||||
protected String getConfigResourceLocation() {
|
||||
return "ehcache.xml";
|
||||
}
|
||||
|
||||
protected boolean useTransactionManager() {
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
41
hibernate-ehcache/src/test/java/org/hibernate/cache/EhCacheRegionFactoryTest.java
vendored
Normal file
41
hibernate-ehcache/src/test/java/org/hibernate/cache/EhCacheRegionFactoryTest.java
vendored
Normal file
@ -0,0 +1,41 @@
|
||||
package org.hibernate.cache;
|
||||
|
||||
import org.hibernate.cfg.Environment;
|
||||
import org.hibernate.testing.junit.functional.FunctionalTestClassTestSuite;
|
||||
import org.hibernate.testing.cache.BaseCacheRegionFactoryTestCase;
|
||||
|
||||
import junit.framework.Test;
|
||||
|
||||
/**
|
||||
* @author Alex Snaps
|
||||
*/
|
||||
public class EhCacheRegionFactoryTest extends BaseCacheRegionFactoryTestCase {
|
||||
|
||||
public EhCacheRegionFactoryTest(String x) {
|
||||
super(x);
|
||||
}
|
||||
|
||||
protected Class getCacheRegionFactory() {
|
||||
return EhCacheRegionFactory.class;
|
||||
}
|
||||
|
||||
public static Test suite() {
|
||||
return new FunctionalTestClassTestSuite(EhCacheRegionFactoryTest.class);
|
||||
}
|
||||
|
||||
public String getCacheConcurrencyStrategy() {
|
||||
return "read-write";
|
||||
}
|
||||
|
||||
protected String getConfigResourceKey() {
|
||||
return Environment.CACHE_PROVIDER_CONFIG;
|
||||
}
|
||||
|
||||
protected String getConfigResourceLocation() {
|
||||
return "ehcache.xml";
|
||||
}
|
||||
|
||||
protected boolean useTransactionManager() {
|
||||
return false;
|
||||
}
|
||||
}
|
@ -42,7 +42,7 @@
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public abstract class BaseCacheProviderTestCase extends FunctionalTestCase {
|
||||
public abstract class BaseCacheProviderTestCase extends BaseCacheTestCase {
|
||||
|
||||
// note that a lot of the fucntionality here is intended to be used
|
||||
// in creating specific tests for each CacheProvider that would extend
|
||||
@ -53,33 +53,12 @@ public BaseCacheProviderTestCase(String x) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getBaseForMappings() {
|
||||
return "org/hibernate/testing/";
|
||||
}
|
||||
|
||||
public String[] getMappings() {
|
||||
return new String[] { "cache/Item.hbm.xml" };
|
||||
}
|
||||
|
||||
public void configure(Configuration cfg) {
|
||||
super.configure( cfg );
|
||||
cfg.setProperty( Environment.CACHE_REGION_PREFIX, "" );
|
||||
cfg.setProperty( Environment.USE_SECOND_LEVEL_CACHE, "true" );
|
||||
cfg.setProperty( Environment.GENERATE_STATISTICS, "true" );
|
||||
cfg.setProperty( Environment.USE_STRUCTURED_CACHE, "true" );
|
||||
protected void configCache(final Configuration cfg) {
|
||||
cfg.setProperty( Environment.CACHE_PROVIDER, getCacheProvider().getName() );
|
||||
|
||||
if ( getConfigResourceKey() != null ) {
|
||||
cfg.setProperty( getConfigResourceKey(), getConfigResourceLocation() );
|
||||
}
|
||||
|
||||
if ( useTransactionManager() ) {
|
||||
cfg.setProperty( Environment.CONNECTION_PROVIDER, ConnectionProviderImpl.class.getName() );
|
||||
cfg.setProperty( Environment.TRANSACTION_MANAGER_STRATEGY, TransactionManagerLookupImpl.class.getName() );
|
||||
}
|
||||
else {
|
||||
cfg.setProperty( Environment.TRANSACTION_STRATEGY, JDBCTransactionFactory.class.getName() );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -89,155 +68,14 @@ public void configure(Configuration cfg) {
|
||||
*/
|
||||
protected abstract Class getCacheProvider();
|
||||
|
||||
/**
|
||||
* For provider-specific configuration, the name of the property key the
|
||||
* provider expects.
|
||||
*
|
||||
* @return The provider-specific config key.
|
||||
*/
|
||||
protected abstract String getConfigResourceKey();
|
||||
|
||||
/**
|
||||
* For provider-specific configuration, the resource location of that
|
||||
* config resource.
|
||||
*
|
||||
* @return The config resource location.
|
||||
*/
|
||||
protected abstract String getConfigResourceLocation();
|
||||
|
||||
/**
|
||||
* Should we use a transaction manager for transaction management.
|
||||
*
|
||||
* @return True if we should use a RM; false otherwise.
|
||||
*/
|
||||
protected abstract boolean useTransactionManager();
|
||||
|
||||
|
||||
public void testQueryCacheInvalidation() {
|
||||
Session s = openSession();
|
||||
Transaction t = s.beginTransaction();
|
||||
Item i = new Item();
|
||||
i.setName("widget");
|
||||
i.setDescription("A really top-quality, full-featured widget.");
|
||||
s.persist(i);
|
||||
t.commit();
|
||||
s.close();
|
||||
|
||||
SecondLevelCacheStatistics slcs = s.getSessionFactory().getStatistics()
|
||||
.getSecondLevelCacheStatistics( Item.class.getName() );
|
||||
|
||||
assertEquals( slcs.getPutCount(), 1 );
|
||||
assertEquals( slcs.getElementCountInMemory(), 1 );
|
||||
assertEquals( slcs.getEntries().size(), 1 );
|
||||
|
||||
s = openSession();
|
||||
t = s.beginTransaction();
|
||||
i = (Item) s.get( Item.class, i.getId() );
|
||||
|
||||
assertEquals( slcs.getHitCount(), 1 );
|
||||
assertEquals( slcs.getMissCount(), 0 );
|
||||
|
||||
i.setDescription("A bog standard item");
|
||||
|
||||
t.commit();
|
||||
s.close();
|
||||
|
||||
assertEquals( slcs.getPutCount(), 2 );
|
||||
|
||||
Object entry = slcs.getEntries().get( i.getId() );
|
||||
Map map;
|
||||
if ( entry instanceof ReadWriteCache.Item ) {
|
||||
map = (Map) ( (ReadWriteCache.Item) entry ).getValue();
|
||||
@Override
|
||||
protected Map getMapFromCachedEntry(final Object entry) {
|
||||
final Map map;
|
||||
if (entry instanceof ReadWriteCache.Item) {
|
||||
map = (Map)((ReadWriteCache.Item)entry).getValue();
|
||||
} else {
|
||||
map = (Map)entry;
|
||||
}
|
||||
else {
|
||||
map = (Map) entry;
|
||||
}
|
||||
assertTrue( map.get("description").equals("A bog standard item") );
|
||||
assertTrue( map.get("name").equals("widget") );
|
||||
|
||||
// cleanup
|
||||
s = openSession();
|
||||
t = s.beginTransaction();
|
||||
s.delete( i );
|
||||
t.commit();
|
||||
s.close();
|
||||
}
|
||||
|
||||
public void testEmptySecondLevelCacheEntry() throws Exception {
|
||||
getSessions().evictEntity( Item.class.getName() );
|
||||
Statistics stats = getSessions().getStatistics();
|
||||
stats.clear();
|
||||
SecondLevelCacheStatistics statistics = stats.getSecondLevelCacheStatistics( Item.class.getName() );
|
||||
Map cacheEntries = statistics.getEntries();
|
||||
assertEquals( 0, cacheEntries.size() );
|
||||
}
|
||||
|
||||
public void testStaleWritesLeaveCacheConsistent() {
|
||||
Session s = openSession();
|
||||
Transaction txn = s.beginTransaction();
|
||||
VersionedItem item = new VersionedItem();
|
||||
item.setName( "steve" );
|
||||
item.setDescription( "steve's item" );
|
||||
s.save( item );
|
||||
txn.commit();
|
||||
s.close();
|
||||
|
||||
Long initialVersion = item.getVersion();
|
||||
|
||||
// manually revert the version property
|
||||
item.setVersion( new Long( item.getVersion().longValue() - 1 ) );
|
||||
|
||||
try {
|
||||
s = openSession();
|
||||
txn = s.beginTransaction();
|
||||
s.update( item );
|
||||
txn.commit();
|
||||
s.close();
|
||||
fail( "expected stale write to fail" );
|
||||
}
|
||||
catch( Throwable expected ) {
|
||||
// expected behavior here
|
||||
if ( txn != null ) {
|
||||
try {
|
||||
txn.rollback();
|
||||
}
|
||||
catch( Throwable ignore ) {
|
||||
}
|
||||
}
|
||||
}
|
||||
finally {
|
||||
if ( s != null && s.isOpen() ) {
|
||||
try {
|
||||
s.close();
|
||||
}
|
||||
catch( Throwable ignore ) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// check the version value in the cache...
|
||||
SecondLevelCacheStatistics slcs = sfi().getStatistics()
|
||||
.getSecondLevelCacheStatistics( VersionedItem.class.getName() );
|
||||
|
||||
Object entry = slcs.getEntries().get( item.getId() );
|
||||
Long cachedVersionValue;
|
||||
if ( entry instanceof ReadWriteCache.Lock ) {
|
||||
//FIXME don't know what to test here
|
||||
cachedVersionValue = new Long( ( (ReadWriteCache.Lock) entry).getUnlockTimestamp() );
|
||||
}
|
||||
else {
|
||||
cachedVersionValue = ( Long ) ( (Map) entry ).get( "_version" );
|
||||
assertEquals( initialVersion.longValue(), cachedVersionValue.longValue() );
|
||||
}
|
||||
|
||||
|
||||
// cleanup
|
||||
s = openSession();
|
||||
txn = s.beginTransaction();
|
||||
item = ( VersionedItem ) s.load( VersionedItem.class, item.getId() );
|
||||
s.delete( item );
|
||||
txn.commit();
|
||||
s.close();
|
||||
|
||||
return map;
|
||||
}
|
||||
}
|
||||
|
45
hibernate-testing/src/main/java/org/hibernate/testing/cache/BaseCacheRegionFactoryTestCase.java
vendored
Normal file
45
hibernate-testing/src/main/java/org/hibernate/testing/cache/BaseCacheRegionFactoryTestCase.java
vendored
Normal file
@ -0,0 +1,45 @@
|
||||
package org.hibernate.testing.cache;
|
||||
|
||||
import org.hibernate.cfg.Configuration;
|
||||
import org.hibernate.cfg.Environment;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author Alex Snaps
|
||||
*/
|
||||
public abstract class BaseCacheRegionFactoryTestCase extends BaseCacheTestCase {
|
||||
public BaseCacheRegionFactoryTestCase(String x) {
|
||||
super(x);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void configCache(final Configuration cfg) {
|
||||
cfg.setProperty(Environment.CACHE_REGION_FACTORY, getCacheRegionFactory().getName());
|
||||
|
||||
if (getConfigResourceKey() != null) {
|
||||
cfg.setProperty(getConfigResourceKey(), getConfigResourceLocation());
|
||||
}
|
||||
}
|
||||
|
||||
protected abstract Class getCacheRegionFactory();
|
||||
|
||||
protected Map getMapFromCachedEntry(final Object entry) {
|
||||
final Map map;
|
||||
if ("net.sf.ehcache.hibernate.strategy.AbstractReadWriteEhcacheAccessStrategy$Item".equals(entry.getClass().getName())) {
|
||||
try {
|
||||
Field field = entry.getClass().getDeclaredField("value");
|
||||
field.setAccessible(true);
|
||||
map = (Map)field.get(entry);
|
||||
} catch (NoSuchFieldException e) {
|
||||
throw new RuntimeException(e);
|
||||
} catch (IllegalAccessException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
} else {
|
||||
map = (Map)entry;
|
||||
}
|
||||
return map;
|
||||
}
|
||||
}
|
198
hibernate-testing/src/main/java/org/hibernate/testing/cache/BaseCacheTestCase.java
vendored
Normal file
198
hibernate-testing/src/main/java/org/hibernate/testing/cache/BaseCacheTestCase.java
vendored
Normal file
@ -0,0 +1,198 @@
|
||||
package org.hibernate.testing.cache;
|
||||
|
||||
import org.hibernate.Session;
|
||||
import org.hibernate.Transaction;
|
||||
import org.hibernate.cache.ReadWriteCache;
|
||||
import org.hibernate.cfg.Configuration;
|
||||
import org.hibernate.cfg.Environment;
|
||||
import org.hibernate.stat.SecondLevelCacheStatistics;
|
||||
import org.hibernate.stat.Statistics;
|
||||
import org.hibernate.testing.junit.functional.FunctionalTestCase;
|
||||
import org.hibernate.testing.tm.ConnectionProviderImpl;
|
||||
import org.hibernate.testing.tm.TransactionManagerLookupImpl;
|
||||
import org.hibernate.transaction.JDBCTransactionFactory;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author Alex Snaps
|
||||
*/
|
||||
public abstract class BaseCacheTestCase extends FunctionalTestCase {
|
||||
public BaseCacheTestCase(final String string) {super(string);}
|
||||
|
||||
@Override
|
||||
public String getBaseForMappings() {
|
||||
return "org/hibernate/testing/";
|
||||
}
|
||||
|
||||
public String[] getMappings() {
|
||||
return new String[] { "cache/Item.hbm.xml" };
|
||||
}
|
||||
|
||||
public void configure(Configuration cfg) {
|
||||
super.configure( cfg );
|
||||
cfg.setProperty( Environment.CACHE_REGION_PREFIX, "" );
|
||||
cfg.setProperty( Environment.USE_SECOND_LEVEL_CACHE, "true" );
|
||||
cfg.setProperty( Environment.GENERATE_STATISTICS, "true" );
|
||||
cfg.setProperty( Environment.USE_STRUCTURED_CACHE, "true" );
|
||||
configCache(cfg);
|
||||
|
||||
if ( useTransactionManager() ) {
|
||||
cfg.setProperty( Environment.CONNECTION_PROVIDER, ConnectionProviderImpl.class.getName() );
|
||||
cfg.setProperty( Environment.TRANSACTION_MANAGER_STRATEGY, TransactionManagerLookupImpl.class.getName() );
|
||||
}
|
||||
else {
|
||||
cfg.setProperty( Environment.TRANSACTION_STRATEGY, JDBCTransactionFactory.class.getName() );
|
||||
}
|
||||
}
|
||||
|
||||
protected abstract void configCache(Configuration cfg);
|
||||
|
||||
/**
|
||||
* For provider-specific configuration, the name of the property key the
|
||||
* provider expects.
|
||||
*
|
||||
* @return The provider-specific config key.
|
||||
*/
|
||||
protected abstract String getConfigResourceKey();
|
||||
|
||||
/**
|
||||
* For provider-specific configuration, the resource location of that
|
||||
* config resource.
|
||||
*
|
||||
* @return The config resource location.
|
||||
*/
|
||||
protected abstract String getConfigResourceLocation();
|
||||
|
||||
/**
|
||||
* Should we use a transaction manager for transaction management.
|
||||
*
|
||||
* @return True if we should use a RM; false otherwise.
|
||||
*/
|
||||
protected abstract boolean useTransactionManager();
|
||||
|
||||
public void testQueryCacheInvalidation() {
|
||||
Session s = openSession();
|
||||
Transaction t = s.beginTransaction();
|
||||
Item i = new Item();
|
||||
i.setName("widget");
|
||||
i.setDescription("A really top-quality, full-featured widget.");
|
||||
s.persist(i);
|
||||
t.commit();
|
||||
s.close();
|
||||
|
||||
SecondLevelCacheStatistics slcs = s.getSessionFactory().getStatistics()
|
||||
.getSecondLevelCacheStatistics( Item.class.getName() );
|
||||
|
||||
assertEquals( slcs.getPutCount(), 1 );
|
||||
assertEquals( slcs.getElementCountInMemory(), 1 );
|
||||
assertEquals( slcs.getEntries().size(), 1 );
|
||||
|
||||
s = openSession();
|
||||
t = s.beginTransaction();
|
||||
i = (Item) s.get( Item.class, i.getId() );
|
||||
|
||||
assertEquals( slcs.getHitCount(), 1 );
|
||||
assertEquals( slcs.getMissCount(), 0 );
|
||||
|
||||
i.setDescription("A bog standard item");
|
||||
|
||||
t.commit();
|
||||
s.close();
|
||||
|
||||
assertEquals( slcs.getPutCount(), 2 );
|
||||
|
||||
Object entry = slcs.getEntries().get( i.getId() );
|
||||
Map map = getMapFromCachedEntry(entry);
|
||||
assertTrue( map.get("description").equals("A bog standard item") );
|
||||
assertTrue( map.get("name").equals("widget") );
|
||||
|
||||
// cleanup
|
||||
s = openSession();
|
||||
t = s.beginTransaction();
|
||||
s.delete( i );
|
||||
t.commit();
|
||||
s.close();
|
||||
}
|
||||
|
||||
public void testEmptySecondLevelCacheEntry() throws Exception {
|
||||
getSessions().evictEntity( Item.class.getName() );
|
||||
Statistics stats = getSessions().getStatistics();
|
||||
stats.clear();
|
||||
SecondLevelCacheStatistics statistics = stats.getSecondLevelCacheStatistics( Item.class.getName() );
|
||||
Map cacheEntries = statistics.getEntries();
|
||||
assertEquals( 0, cacheEntries.size() );
|
||||
}
|
||||
|
||||
public void testStaleWritesLeaveCacheConsistent() {
|
||||
Session s = openSession();
|
||||
Transaction txn = s.beginTransaction();
|
||||
VersionedItem item = new VersionedItem();
|
||||
item.setName( "steve" );
|
||||
item.setDescription( "steve's item" );
|
||||
s.save( item );
|
||||
txn.commit();
|
||||
s.close();
|
||||
|
||||
Long initialVersion = item.getVersion();
|
||||
|
||||
// manually revert the version property
|
||||
item.setVersion( new Long( item.getVersion().longValue() - 1 ) );
|
||||
|
||||
try {
|
||||
s = openSession();
|
||||
txn = s.beginTransaction();
|
||||
s.update( item );
|
||||
txn.commit();
|
||||
s.close();
|
||||
fail( "expected stale write to fail" );
|
||||
}
|
||||
catch( Throwable expected ) {
|
||||
// expected behavior here
|
||||
if ( txn != null ) {
|
||||
try {
|
||||
txn.rollback();
|
||||
}
|
||||
catch( Throwable ignore ) {
|
||||
}
|
||||
}
|
||||
}
|
||||
finally {
|
||||
if ( s != null && s.isOpen() ) {
|
||||
try {
|
||||
s.close();
|
||||
}
|
||||
catch( Throwable ignore ) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// check the version value in the cache...
|
||||
SecondLevelCacheStatistics slcs = sfi().getStatistics()
|
||||
.getSecondLevelCacheStatistics( VersionedItem.class.getName() );
|
||||
|
||||
Object entry = slcs.getEntries().get( item.getId() );
|
||||
Long cachedVersionValue;
|
||||
if ( entry instanceof ReadWriteCache.Lock ) {
|
||||
//FIXME don't know what to test here
|
||||
cachedVersionValue = new Long( ( (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, which is the same as issue as above...
|
||||
} else {
|
||||
cachedVersionValue = ( Long ) getMapFromCachedEntry(entry).get( "_version" );
|
||||
assertEquals( initialVersion.longValue(), cachedVersionValue.longValue() );
|
||||
}
|
||||
|
||||
|
||||
// cleanup
|
||||
s = openSession();
|
||||
txn = s.beginTransaction();
|
||||
item = ( VersionedItem ) s.load( VersionedItem.class, item.getId() );
|
||||
s.delete( item );
|
||||
txn.commit();
|
||||
s.close();
|
||||
|
||||
}
|
||||
|
||||
protected abstract Map getMapFromCachedEntry(Object entry);
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user