diff --git a/annotations/src/main/java/org/hibernate/annotations/CacheConcurrencyStrategy.java b/annotations/src/main/java/org/hibernate/annotations/CacheConcurrencyStrategy.java index eeff38613c..0b10706a39 100644 --- a/annotations/src/main/java/org/hibernate/annotations/CacheConcurrencyStrategy.java +++ b/annotations/src/main/java/org/hibernate/annotations/CacheConcurrencyStrategy.java @@ -23,15 +23,67 @@ */ package org.hibernate.annotations; +import org.hibernate.cache.access.AccessType; + /** * Cache concurrency strategy * * @author Emmanuel Bernard */ public enum CacheConcurrencyStrategy { - NONE, - READ_ONLY, - NONSTRICT_READ_WRITE, - READ_WRITE, - TRANSACTIONAL + NONE( null ), + READ_ONLY( AccessType.READ_ONLY ), + NONSTRICT_READ_WRITE( AccessType.NONSTRICT_READ_WRITE ), + READ_WRITE( AccessType.READ_WRITE ), + TRANSACTIONAL( AccessType.TRANSACTIONAL ); + + private final AccessType accessType; + + private CacheConcurrencyStrategy(AccessType accessType) { + this.accessType = accessType; + } + + public static CacheConcurrencyStrategy fromAccessType(AccessType accessType) { + final String name = accessType == null ? null : accessType.getName(); + if ( AccessType.READ_ONLY.getName().equals( name ) ) { + return READ_ONLY; + } + else if ( AccessType.READ_WRITE.getName().equals( name ) ) { + return READ_WRITE; + } + else if ( AccessType.NONSTRICT_READ_WRITE.getName().equals( name ) ) { + return NONSTRICT_READ_WRITE; + } + else if ( AccessType.TRANSACTIONAL.getName().equals( name ) ) { + return TRANSACTIONAL; + } + else { + return NONE; + } + } + + public static CacheConcurrencyStrategy parse(String name) { + if ( READ_ONLY.accessType.getName().equalsIgnoreCase( name ) ) { + return READ_ONLY; + } + else if ( READ_WRITE.accessType.getName().equalsIgnoreCase( name ) ) { + return READ_WRITE; + } + else if ( NONSTRICT_READ_WRITE.accessType.getName().equalsIgnoreCase( name ) ) { + return NONSTRICT_READ_WRITE; + } + else if ( TRANSACTIONAL.accessType.getName().equalsIgnoreCase( name ) ) { + return TRANSACTIONAL; + } + else if ( "none".equalsIgnoreCase( name ) ) { + return NONE; + } + else { + return null; + } + } + + public AccessType toAccessType() { + return accessType; + } } diff --git a/annotations/src/main/java/org/hibernate/cfg/AnnotationBinder.java b/annotations/src/main/java/org/hibernate/cfg/AnnotationBinder.java index 847bf9e318..1411cb5bf4 100644 --- a/annotations/src/main/java/org/hibernate/cfg/AnnotationBinder.java +++ b/annotations/src/main/java/org/hibernate/cfg/AnnotationBinder.java @@ -814,12 +814,33 @@ public final class AnnotationBinder { private static CacheConcurrencyStrategy DEFAULT_CACHE_CONCURRENCY_STRATEGY; + static void prepareDefaultCacheConcurrencyStrategy(Properties properties) { + if ( DEFAULT_CACHE_CONCURRENCY_STRATEGY != null ) { + log.info( "Default cache concurrency strategy already defined" ); + return; + } + + if ( ! properties.containsKey( AnnotationConfiguration.DEFAULT_CACHE_CONCURRENCY_STRATEGY ) ) { + log.trace( "Given properties did not contain any default cache concurrency strategy setting" ); + return; + } + + final String strategyName = properties.getProperty( AnnotationConfiguration.DEFAULT_CACHE_CONCURRENCY_STRATEGY ); + log.trace( "Discovered default cache concurrency strategy via config [" + strategyName + "]" ); + CacheConcurrencyStrategy strategy = CacheConcurrencyStrategy.parse( strategyName ); + if ( strategy == null ) { + log.trace( "Discovered default cache concurrency strategy specified nothing" ); + return; + } + + log.info( "Setting default cache concurrency strategy via config [" + strategy.name() + "]" ); + DEFAULT_CACHE_CONCURRENCY_STRATEGY = strategy; + } + private static CacheConcurrencyStrategy determineCacheConcurrencyStrategy(ExtendedMappings mappings) { if ( DEFAULT_CACHE_CONCURRENCY_STRATEGY == null ) { -// todo need to figure out how we will determine the default cache access-type/concurrency-strategy -// RegionFactory cacheRegionFactory = SettingsFactory.createRegionFactory( mappings.getConfigurationProperties(), true ); -// DEFAULT_CACHE_CONCURRENCY_STRATEGY = cacheRegionFactory.[getDefault...] - DEFAULT_CACHE_CONCURRENCY_STRATEGY = CacheConcurrencyStrategy.TRANSACTIONAL; + final RegionFactory cacheRegionFactory = SettingsFactory.createRegionFactory( mappings.getConfigurationProperties(), true ); + DEFAULT_CACHE_CONCURRENCY_STRATEGY = CacheConcurrencyStrategy.fromAccessType( cacheRegionFactory.getDefaultAccessType() ); } return DEFAULT_CACHE_CONCURRENCY_STRATEGY; } diff --git a/annotations/src/main/java/org/hibernate/cfg/AnnotationConfiguration.java b/annotations/src/main/java/org/hibernate/cfg/AnnotationConfiguration.java index be162e4a80..84aad22d86 100644 --- a/annotations/src/main/java/org/hibernate/cfg/AnnotationConfiguration.java +++ b/annotations/src/main/java/org/hibernate/cfg/AnnotationConfiguration.java @@ -105,6 +105,13 @@ import org.hibernate.util.CollectionHelper; public class AnnotationConfiguration extends Configuration { private Logger log = LoggerFactory.getLogger( AnnotationConfiguration.class ); + /** + * Setting used to give the name of the default {@link org.hibernate.annotations.CacheConcurrencyStrategy} + * to use when either {@link javax.persistence.Cacheable @Cacheable} or + * {@link Cache @Cache} is used. {@link Cache @Cache(strategy=".."} is used to override. + */ + public static final String DEFAULT_CACHE_CONCURRENCY_STRATEGY = "org.hibernate.cache.default_cache_concurrency_strategy"; + /** * Class name of the class needed to enable Search. */ diff --git a/annotations/src/main/java/org/hibernate/cfg/annotations/EntityBinder.java b/annotations/src/main/java/org/hibernate/cfg/annotations/EntityBinder.java index 88fec5b7a9..d708a9b9fd 100644 --- a/annotations/src/main/java/org/hibernate/cfg/annotations/EntityBinder.java +++ b/annotations/src/main/java/org/hibernate/cfg/annotations/EntityBinder.java @@ -771,20 +771,8 @@ public class EntityBinder { } public static String getCacheConcurrencyStrategy(CacheConcurrencyStrategy strategy) { - switch ( strategy ) { - case NONE: - return null; - case READ_ONLY: - return org.hibernate.cache.access.AccessType.READ_ONLY.getName(); - case READ_WRITE: - return org.hibernate.cache.access.AccessType.READ_WRITE.getName(); - case NONSTRICT_READ_WRITE: - return org.hibernate.cache.access.AccessType.NONSTRICT_READ_WRITE.getName(); - case TRANSACTIONAL: - return org.hibernate.cache.access.AccessType.TRANSACTIONAL.getName(); - default: - throw new AssertionFailure( "CacheConcurrencyStrategy unknown: " + strategy ); - } + org.hibernate.cache.access.AccessType accessType = strategy.toAccessType(); + return accessType == null ? null : accessType.getName(); } public void addFilter(String name, String condition) { diff --git a/cache-infinispan/src/main/java/org/hibernate/cache/infinispan/InfinispanRegionFactory.java b/cache-infinispan/src/main/java/org/hibernate/cache/infinispan/InfinispanRegionFactory.java index f2aa21bf4d..9011fe328e 100644 --- a/cache-infinispan/src/main/java/org/hibernate/cache/infinispan/InfinispanRegionFactory.java +++ b/cache-infinispan/src/main/java/org/hibernate/cache/infinispan/InfinispanRegionFactory.java @@ -18,6 +18,7 @@ import org.hibernate.cache.EntityRegion; import org.hibernate.cache.QueryResultsRegion; import org.hibernate.cache.RegionFactory; import org.hibernate.cache.TimestampsRegion; +import org.hibernate.cache.access.AccessType; import org.hibernate.cache.infinispan.collection.CollectionRegionImpl; import org.hibernate.cache.infinispan.entity.EntityRegionImpl; import org.hibernate.cache.infinispan.query.QueryResultsRegionImpl; @@ -205,7 +206,12 @@ public class InfinispanRegionFactory implements RegionFactory { return true; } - /** + @Override + public AccessType getDefaultAccessType() { + return AccessType.TRANSACTIONAL; + } + + /** * {@inheritDoc} */ public long nextTimestamp() { diff --git a/cache-infinispan/src/test/java/org/hibernate/test/cache/infinispan/functional/cluster/ClusterAwareRegionFactory.java b/cache-infinispan/src/test/java/org/hibernate/test/cache/infinispan/functional/cluster/ClusterAwareRegionFactory.java index 6bf014ed56..7555fe7693 100644 --- a/cache-infinispan/src/test/java/org/hibernate/test/cache/infinispan/functional/cluster/ClusterAwareRegionFactory.java +++ b/cache-infinispan/src/test/java/org/hibernate/test/cache/infinispan/functional/cluster/ClusterAwareRegionFactory.java @@ -31,6 +31,7 @@ import org.hibernate.cache.EntityRegion; import org.hibernate.cache.QueryResultsRegion; import org.hibernate.cache.RegionFactory; import org.hibernate.cache.TimestampsRegion; +import org.hibernate.cache.access.AccessType; import org.hibernate.cache.infinispan.InfinispanRegionFactory; import org.hibernate.cfg.Settings; import org.infinispan.manager.CacheManager; @@ -117,7 +118,12 @@ public class ClusterAwareRegionFactory implements RegionFactory { return delegate.isMinimalPutsEnabledByDefault(); } - public long nextTimestamp() { + @Override + public AccessType getDefaultAccessType() { + return AccessType.TRANSACTIONAL; + } + + public long nextTimestamp() { return delegate.nextTimestamp(); } } diff --git a/cache-jbosscache/src/main/java/org/hibernate/cache/jbc/JBossCacheRegionFactory.java b/cache-jbosscache/src/main/java/org/hibernate/cache/jbc/JBossCacheRegionFactory.java index fb43e3bb3c..102952441d 100755 --- a/cache-jbosscache/src/main/java/org/hibernate/cache/jbc/JBossCacheRegionFactory.java +++ b/cache-jbosscache/src/main/java/org/hibernate/cache/jbc/JBossCacheRegionFactory.java @@ -32,6 +32,7 @@ import org.hibernate.cache.EntityRegion; import org.hibernate.cache.QueryResultsRegion; import org.hibernate.cache.RegionFactory; import org.hibernate.cache.TimestampsRegion; +import org.hibernate.cache.access.AccessType; import org.hibernate.cache.jbc.builder.JndiSharedCacheInstanceManager; import org.hibernate.cache.jbc.builder.SharedCacheInstanceManager; import org.hibernate.cache.jbc.collection.CollectionRegionImpl; @@ -116,7 +117,11 @@ public class JBossCacheRegionFactory implements RegionFactory { return true; } - public long nextTimestamp() { + public AccessType getDefaultAccessType() { + return AccessType.TRANSACTIONAL; + } + + public long nextTimestamp() { return System.currentTimeMillis() / 100; } diff --git a/core/src/main/java/org/hibernate/cache/RegionFactory.java b/core/src/main/java/org/hibernate/cache/RegionFactory.java index 6bb7428b26..2a1646f95f 100644 --- a/core/src/main/java/org/hibernate/cache/RegionFactory.java +++ b/core/src/main/java/org/hibernate/cache/RegionFactory.java @@ -26,6 +26,7 @@ package org.hibernate.cache; import java.util.Properties; +import org.hibernate.cache.access.AccessType; import org.hibernate.cfg.Settings; /** @@ -76,6 +77,14 @@ public interface RegionFactory { */ public boolean isMinimalPutsEnabledByDefault(); + /** + * Get the default access type for {@link EntityRegion entity} and + * {@link CollectionRegion collection} regions. + * + * @return This factory's default access type. + */ + public AccessType getDefaultAccessType(); + /** * Generate a timestamp. *

diff --git a/core/src/main/java/org/hibernate/cache/impl/NoCachingRegionFactory.java b/core/src/main/java/org/hibernate/cache/impl/NoCachingRegionFactory.java index f2c704ef73..352d65f60f 100644 --- a/core/src/main/java/org/hibernate/cache/impl/NoCachingRegionFactory.java +++ b/core/src/main/java/org/hibernate/cache/impl/NoCachingRegionFactory.java @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * 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 Middleware LLC. + * 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 @@ -20,7 +20,6 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate.cache.impl; @@ -34,6 +33,7 @@ import org.hibernate.cache.QueryResultsRegion; import org.hibernate.cache.TimestampsRegion; import org.hibernate.cache.NoCachingEnabledException; import org.hibernate.cache.CacheDataDescription; +import org.hibernate.cache.access.AccessType; import org.hibernate.cfg.Settings; /** @@ -57,6 +57,10 @@ public class NoCachingRegionFactory implements RegionFactory { return false; } + public AccessType getDefaultAccessType() { + return null; + } + public long nextTimestamp() { return System.currentTimeMillis() / 100; } diff --git a/core/src/main/java/org/hibernate/cache/impl/bridge/RegionFactoryCacheProviderBridge.java b/core/src/main/java/org/hibernate/cache/impl/bridge/RegionFactoryCacheProviderBridge.java index f26f4c6d46..9f216dffa4 100644 --- a/core/src/main/java/org/hibernate/cache/impl/bridge/RegionFactoryCacheProviderBridge.java +++ b/core/src/main/java/org/hibernate/cache/impl/bridge/RegionFactoryCacheProviderBridge.java @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * 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 Middleware LLC. + * 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 @@ -20,7 +20,6 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate.cache.impl.bridge; @@ -38,6 +37,7 @@ import org.hibernate.cache.QueryResultsRegion; import org.hibernate.cache.NoCacheProvider; import org.hibernate.cache.TimestampsRegion; import org.hibernate.cache.CacheDataDescription; +import org.hibernate.cache.access.AccessType; import org.hibernate.util.PropertiesHelper; import org.hibernate.util.ReflectHelper; import org.hibernate.cfg.Environment; @@ -81,6 +81,14 @@ public class RegionFactoryCacheProviderBridge implements RegionFactory { return cacheProvider.isMinimalPutsEnabledByDefault(); } + /** + * {@inheritDoc} + */ + public AccessType getDefaultAccessType() { + // we really have no idea + return null; + } + public long nextTimestamp() { return cacheProvider.nextTimestamp(); }