HHH-4659 - Add support for standard declarative cache (@Cacheable)
git-svn-id: https://svn.jboss.org/repos/hibernate/core/trunk@18605 1b8cb986-b30d-0410-93ca-fae66ebed9b2
This commit is contained in:
parent
70ddcd81f2
commit
d24ed1a1d3
|
@ -24,6 +24,7 @@
|
|||
*/
|
||||
package org.hibernate.cfg;
|
||||
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
|
@ -36,6 +37,7 @@ import java.util.Map;
|
|||
import java.util.Properties;
|
||||
import java.util.Set;
|
||||
import javax.persistence.Basic;
|
||||
import javax.persistence.Cacheable;
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.DiscriminatorType;
|
||||
import javax.persistence.DiscriminatorValue;
|
||||
|
@ -66,6 +68,7 @@ import javax.persistence.OneToOne;
|
|||
import javax.persistence.PrimaryKeyJoinColumn;
|
||||
import javax.persistence.PrimaryKeyJoinColumns;
|
||||
import javax.persistence.SequenceGenerator;
|
||||
import javax.persistence.SharedCacheMode;
|
||||
import javax.persistence.SqlResultSetMapping;
|
||||
import javax.persistence.SqlResultSetMappings;
|
||||
import javax.persistence.Table;
|
||||
|
@ -86,6 +89,7 @@ import org.hibernate.FetchMode;
|
|||
import org.hibernate.MappingException;
|
||||
import org.hibernate.annotations.BatchSize;
|
||||
import org.hibernate.annotations.Cache;
|
||||
import org.hibernate.annotations.CacheConcurrencyStrategy;
|
||||
import org.hibernate.annotations.Cascade;
|
||||
import org.hibernate.annotations.CascadeType;
|
||||
import org.hibernate.annotations.Check;
|
||||
|
@ -128,6 +132,7 @@ import org.hibernate.annotations.common.reflection.XClass;
|
|||
import org.hibernate.annotations.common.reflection.XMethod;
|
||||
import org.hibernate.annotations.common.reflection.XPackage;
|
||||
import org.hibernate.annotations.common.reflection.XProperty;
|
||||
import org.hibernate.cache.RegionFactory;
|
||||
import org.hibernate.cfg.annotations.CollectionBinder;
|
||||
import org.hibernate.cfg.annotations.EntityBinder;
|
||||
import org.hibernate.cfg.annotations.Nullability;
|
||||
|
@ -505,9 +510,9 @@ public final class AnnotationBinder {
|
|||
org.hibernate.annotations.Entity hibEntityAnn = clazzToProcess.getAnnotation(
|
||||
org.hibernate.annotations.Entity.class
|
||||
);
|
||||
org.hibernate.annotations.Cache cacheAnn = clazzToProcess.getAnnotation(
|
||||
org.hibernate.annotations.Cache.class
|
||||
);
|
||||
|
||||
Cache cacheAnn = determineCacheSettings( clazzToProcess, mappings );
|
||||
|
||||
EntityBinder entityBinder = new EntityBinder(
|
||||
entityAnn, hibEntityAnn, clazzToProcess, persistentClass, mappings
|
||||
);
|
||||
|
@ -765,6 +770,84 @@ public final class AnnotationBinder {
|
|||
|
||||
}
|
||||
|
||||
private static Cache determineCacheSettings(XClass clazzToProcess, ExtendedMappings mappings) {
|
||||
Cache cacheAnn = clazzToProcess.getAnnotation( Cache.class );
|
||||
if ( cacheAnn != null ) {
|
||||
return cacheAnn;
|
||||
}
|
||||
|
||||
Cacheable cacheableAnn = clazzToProcess.getAnnotation( Cacheable.class );
|
||||
SharedCacheMode mode = (SharedCacheMode) mappings.getConfigurationProperties().get(
|
||||
"javax.persistence.sharedCache.mode"
|
||||
);
|
||||
switch ( mode ) {
|
||||
case ALL: {
|
||||
cacheAnn = buildCacheMock( clazzToProcess.getName(), mappings );
|
||||
break;
|
||||
}
|
||||
case ENABLE_SELECTIVE: {
|
||||
if ( cacheableAnn != null && cacheableAnn.value() ) {
|
||||
cacheAnn = buildCacheMock( clazzToProcess.getName(), mappings );
|
||||
}
|
||||
break;
|
||||
}
|
||||
case DISABLE_SELECTIVE: {
|
||||
if ( cacheableAnn == null || cacheableAnn.value() ) {
|
||||
cacheAnn = buildCacheMock( clazzToProcess.getName(), mappings );
|
||||
}
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
// treat both NONE and UNSPECIFIED the same
|
||||
break;
|
||||
}
|
||||
}
|
||||
return cacheAnn;
|
||||
}
|
||||
|
||||
private static Cache buildCacheMock(String region, ExtendedMappings mappings) {
|
||||
return new LocalCacheAnnotationImpl( region, determineCacheConcurrencyStrategy( mappings ) );
|
||||
}
|
||||
|
||||
private static CacheConcurrencyStrategy DEFAULT_CACHE_CONCURRENCY_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;
|
||||
}
|
||||
return DEFAULT_CACHE_CONCURRENCY_STRATEGY;
|
||||
}
|
||||
|
||||
@SuppressWarnings({ "ClassExplicitlyAnnotation" })
|
||||
private static class LocalCacheAnnotationImpl implements Cache {
|
||||
private final String region;
|
||||
private final CacheConcurrencyStrategy usage;
|
||||
|
||||
private LocalCacheAnnotationImpl(String region, CacheConcurrencyStrategy usage) {
|
||||
this.region = region;
|
||||
this.usage = usage;
|
||||
}
|
||||
|
||||
public CacheConcurrencyStrategy usage() {
|
||||
return usage;
|
||||
}
|
||||
|
||||
public String region() {
|
||||
return region;
|
||||
}
|
||||
|
||||
public String include() {
|
||||
return "all";
|
||||
}
|
||||
|
||||
public Class<? extends Annotation> annotationType() {
|
||||
return Cache.class;
|
||||
}
|
||||
}
|
||||
|
||||
private static PersistentClass makePersistentClass(InheritanceState inheritanceState, PersistentClass superEntity) {
|
||||
//we now know what kind of persistent entity it is
|
||||
PersistentClass persistentClass;
|
||||
|
|
|
@ -68,6 +68,7 @@ import org.hibernate.MappingException;
|
|||
import org.hibernate.Session;
|
||||
import org.hibernate.SessionFactory;
|
||||
import org.hibernate.annotations.AnyMetaDef;
|
||||
import org.hibernate.annotations.Cache;
|
||||
import org.hibernate.annotations.common.reflection.MetadataProvider;
|
||||
import org.hibernate.annotations.common.reflection.MetadataProviderInjector;
|
||||
import org.hibernate.annotations.common.reflection.ReflectionManager;
|
||||
|
|
|
@ -30,6 +30,7 @@ import java.util.Properties;
|
|||
import org.hibernate.AnnotationException;
|
||||
import org.hibernate.MappingException;
|
||||
import org.hibernate.annotations.AnyMetaDef;
|
||||
import org.hibernate.annotations.Cache;
|
||||
import org.hibernate.annotations.common.reflection.ReflectionManager;
|
||||
import org.hibernate.annotations.common.reflection.XClass;
|
||||
import org.hibernate.engine.NamedQueryDefinition;
|
||||
|
|
|
@ -474,7 +474,7 @@ public class Configuration implements Serializable {
|
|||
/**
|
||||
* <b>INTENDED FOR TESTSUITE USE ONLY!</b>
|
||||
* <p/>
|
||||
* Much like {@link addCacheableFile(File)} except that here we will fail immediately if
|
||||
* Much like {@link #addCacheableFile(File)} except that here we will fail immediately if
|
||||
* the cache version cannot be found or used for whatever reason
|
||||
*
|
||||
* @param xmlFile The xml file, not the bin!
|
||||
|
@ -2797,6 +2797,10 @@ public class Configuration implements Serializable {
|
|||
public ObjectNameNormalizer getObjectNameNormalizer() {
|
||||
return normalizer;
|
||||
}
|
||||
|
||||
public Properties getConfigurationProperties() {
|
||||
return properties;
|
||||
}
|
||||
}
|
||||
|
||||
final ObjectNameNormalizer normalizer = new ObjectNameNormalizerImpl();
|
||||
|
|
|
@ -550,4 +550,11 @@ public interface Mappings {
|
|||
* @return The normalizer.
|
||||
*/
|
||||
public ObjectNameNormalizer getObjectNameNormalizer();
|
||||
|
||||
/**
|
||||
* Retrieve the configuration properties currently in effect.
|
||||
*
|
||||
* @return The configuration properties
|
||||
*/
|
||||
public Properties getConfigurationProperties();
|
||||
}
|
|
@ -380,7 +380,7 @@ public class SettingsFactory implements Serializable {
|
|||
}
|
||||
}
|
||||
|
||||
protected RegionFactory createRegionFactory(Properties properties, boolean cachingEnabled) {
|
||||
public static RegionFactory createRegionFactory(Properties properties, boolean cachingEnabled) {
|
||||
String regionFactoryClassName = PropertiesHelper.getString( Environment.CACHE_REGION_FACTORY, properties, null );
|
||||
if ( regionFactoryClassName == null && cachingEnabled ) {
|
||||
String providerClassName = PropertiesHelper.getString( Environment.CACHE_PROVIDER, properties, null );
|
||||
|
|
|
@ -0,0 +1,120 @@
|
|||
/*
|
||||
* 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.ejb.test.cacheable.annotation;
|
||||
|
||||
import java.util.Properties;
|
||||
import javax.persistence.SharedCacheMode;
|
||||
|
||||
import org.hibernate.ejb.AvailableSettings;
|
||||
import org.hibernate.ejb.Ejb3Configuration;
|
||||
import org.hibernate.junit.UnitTestCase;
|
||||
import org.hibernate.mapping.PersistentClass;
|
||||
|
||||
/**
|
||||
* TODO : javadoc
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public class ConfigurationTest extends UnitTestCase {
|
||||
public ConfigurationTest(String string) {
|
||||
super( string );
|
||||
}
|
||||
|
||||
public void testSharedCacheModeNone() {
|
||||
Ejb3Configuration config = buildConfiguration( SharedCacheMode.NONE );
|
||||
|
||||
PersistentClass pc = config.getClassMapping( ExplicitlyCacheableEntity.class.getName() );
|
||||
assertNull( pc.getCacheConcurrencyStrategy() );
|
||||
|
||||
pc = config.getClassMapping( ExplicitlyNonCacheableEntity.class.getName() );
|
||||
assertNull( pc.getCacheConcurrencyStrategy() );
|
||||
|
||||
pc = config.getClassMapping( NoCacheableAnnotationEntity.class.getName() );
|
||||
assertNull( pc.getCacheConcurrencyStrategy() );
|
||||
}
|
||||
|
||||
public void testSharedCacheModeUnspecified() {
|
||||
Ejb3Configuration config = buildConfiguration( SharedCacheMode.UNSPECIFIED );
|
||||
|
||||
PersistentClass pc = config.getClassMapping( ExplicitlyCacheableEntity.class.getName() );
|
||||
assertNull( pc.getCacheConcurrencyStrategy() );
|
||||
|
||||
pc = config.getClassMapping( ExplicitlyNonCacheableEntity.class.getName() );
|
||||
assertNull( pc.getCacheConcurrencyStrategy() );
|
||||
|
||||
pc = config.getClassMapping( NoCacheableAnnotationEntity.class.getName() );
|
||||
assertNull( pc.getCacheConcurrencyStrategy() );
|
||||
}
|
||||
|
||||
public void testSharedCacheModeAll() {
|
||||
Ejb3Configuration config = buildConfiguration( SharedCacheMode.ALL );
|
||||
|
||||
PersistentClass pc = config.getClassMapping( ExplicitlyCacheableEntity.class.getName() );
|
||||
assertNotNull( pc.getCacheConcurrencyStrategy() );
|
||||
|
||||
pc = config.getClassMapping( ExplicitlyNonCacheableEntity.class.getName() );
|
||||
assertNotNull( pc.getCacheConcurrencyStrategy() );
|
||||
|
||||
pc = config.getClassMapping( NoCacheableAnnotationEntity.class.getName() );
|
||||
assertNotNull( pc.getCacheConcurrencyStrategy() );
|
||||
}
|
||||
|
||||
public void testSharedCacheModeEnable() {
|
||||
Ejb3Configuration config = buildConfiguration( SharedCacheMode.ENABLE_SELECTIVE );
|
||||
|
||||
PersistentClass pc = config.getClassMapping( ExplicitlyCacheableEntity.class.getName() );
|
||||
assertNotNull( pc.getCacheConcurrencyStrategy() );
|
||||
|
||||
pc = config.getClassMapping( ExplicitlyNonCacheableEntity.class.getName() );
|
||||
assertNull( pc.getCacheConcurrencyStrategy() );
|
||||
|
||||
pc = config.getClassMapping( NoCacheableAnnotationEntity.class.getName() );
|
||||
assertNull( pc.getCacheConcurrencyStrategy() );
|
||||
}
|
||||
|
||||
public void testSharedCacheModeDisable() {
|
||||
Ejb3Configuration config = buildConfiguration( SharedCacheMode.DISABLE_SELECTIVE );
|
||||
|
||||
PersistentClass pc = config.getClassMapping( ExplicitlyCacheableEntity.class.getName() );
|
||||
assertNotNull( pc.getCacheConcurrencyStrategy() );
|
||||
|
||||
pc = config.getClassMapping( ExplicitlyNonCacheableEntity.class.getName() );
|
||||
assertNull( pc.getCacheConcurrencyStrategy() );
|
||||
|
||||
pc = config.getClassMapping( NoCacheableAnnotationEntity.class.getName() );
|
||||
assertNotNull( pc.getCacheConcurrencyStrategy() );
|
||||
}
|
||||
|
||||
private Ejb3Configuration buildConfiguration(SharedCacheMode mode) {
|
||||
Properties properties = new Properties();
|
||||
properties.put( AvailableSettings.SHARED_CACHE_MODE, mode );
|
||||
Ejb3Configuration config = new Ejb3Configuration();
|
||||
config.setProperties( properties );
|
||||
config.addAnnotatedClass( ExplicitlyCacheableEntity.class );
|
||||
config.addAnnotatedClass( ExplicitlyNonCacheableEntity.class );
|
||||
config.addAnnotatedClass( NoCacheableAnnotationEntity.class );
|
||||
config.buildMappings();
|
||||
return config;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,57 @@
|
|||
/*
|
||||
* 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.ejb.test.cacheable.annotation;
|
||||
|
||||
import javax.persistence.Cacheable;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.Id;
|
||||
|
||||
/**
|
||||
* TODO : javadoc
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
@Entity
|
||||
@Cacheable
|
||||
public class ExplicitlyCacheableEntity {
|
||||
private Long id;
|
||||
private String name;
|
||||
|
||||
@Id
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(Long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,57 @@
|
|||
/*
|
||||
* 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.ejb.test.cacheable.annotation;
|
||||
|
||||
import javax.persistence.Cacheable;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.Id;
|
||||
|
||||
/**
|
||||
* TODO : javadoc
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
@Entity
|
||||
@Cacheable(false)
|
||||
public class ExplicitlyNonCacheableEntity {
|
||||
private Long id;
|
||||
private String name;
|
||||
|
||||
@Id
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(Long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,56 @@
|
|||
/*
|
||||
* 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.ejb.test.cacheable.annotation;
|
||||
|
||||
import javax.persistence.Cacheable;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.Id;
|
||||
|
||||
/**
|
||||
* TODO : javadoc
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
@Entity
|
||||
public class NoCacheableAnnotationEntity {
|
||||
private Long id;
|
||||
private String name;
|
||||
|
||||
@Id
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(Long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue