HHH-6974 Class level naturalId cache and stats
Add class level @NaturalIdCache annotation to denote if second level natualId caching should be done Flush out stats model for naturalId cache related stats Add ehcache support classes for naturalId region
This commit is contained in:
parent
72fe79a3f2
commit
c473520585
|
@ -23,17 +23,18 @@
|
|||
*/
|
||||
package org.hibernate.annotations;
|
||||
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
import static java.lang.annotation.ElementType.FIELD;
|
||||
import static java.lang.annotation.ElementType.METHOD;
|
||||
import static java.lang.annotation.RetentionPolicy.RUNTIME;
|
||||
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
/**
|
||||
* This specifies that a property is part of the natural id of the entity.
|
||||
*
|
||||
* @author Nicol<EFBFBD>s Lichtmaier
|
||||
* @see NaturalIdCache
|
||||
*/
|
||||
@Target( { METHOD, FIELD } )
|
||||
@Retention( RUNTIME )
|
||||
|
@ -44,11 +45,4 @@ public @interface NaturalId {
|
|||
* @return {@code true} indicates the natural id is mutable; {@code false} (the default) that it is immutable.
|
||||
*/
|
||||
boolean mutable() default false;
|
||||
|
||||
/**
|
||||
* Should the mapping of this natural id to the primary id be cached
|
||||
*
|
||||
* @return {@code true} (the default) indicates the natural id mapping should be cached; {@code false} that the mapping should not be cached.
|
||||
*/
|
||||
boolean cache() default true;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,44 @@
|
|||
/*
|
||||
* 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.annotations;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
import static java.lang.annotation.ElementType.FIELD;
|
||||
import static java.lang.annotation.ElementType.METHOD;
|
||||
import static java.lang.annotation.ElementType.TYPE;
|
||||
import static java.lang.annotation.RetentionPolicy.RUNTIME;
|
||||
|
||||
/**
|
||||
* Add caching strategy for the NaturalId to Id of a root entity that has a natural id
|
||||
*
|
||||
* @author Eric Dalquist
|
||||
* @see NaturalId
|
||||
*/
|
||||
@Target({TYPE, METHOD, FIELD})
|
||||
@Retention(RUNTIME)
|
||||
public @interface NaturalIdCache {
|
||||
/** cache region name, defaults to full.entity.Name##NaturalId */
|
||||
String region() default "";
|
||||
}
|
|
@ -0,0 +1,47 @@
|
|||
/*
|
||||
* 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 org.hibernate.cache.CacheException;
|
||||
import org.hibernate.cache.spi.access.AccessType;
|
||||
import org.hibernate.cache.spi.access.NaturalIdRegionAccessStrategy;
|
||||
|
||||
/**
|
||||
* Defines the contract for a cache region which will specifically be used to
|
||||
* store naturalId data.
|
||||
*
|
||||
* @author Eric Dalquist
|
||||
*/
|
||||
public interface NaturalIdRegion extends TransactionalDataRegion {
|
||||
|
||||
/**
|
||||
* Build an access strategy for the requested access type.
|
||||
*
|
||||
* @param accessType The type of access strategy to build; never null.
|
||||
* @return The appropriate strategy contract for accessing this region
|
||||
* for the requested type of access.
|
||||
* @throws org.hibernate.cache.CacheException Usually indicates mis-configuration.
|
||||
*/
|
||||
public NaturalIdRegionAccessStrategy buildAccessStrategy(AccessType accessType) throws CacheException;
|
||||
}
|
50
hibernate-core/src/main/java/org/hibernate/cache/spi/access/NaturalIdRegionAccessStrategy.java
vendored
Normal file
50
hibernate-core/src/main/java/org/hibernate/cache/spi/access/NaturalIdRegionAccessStrategy.java
vendored
Normal file
|
@ -0,0 +1,50 @@
|
|||
/*
|
||||
* 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.access;
|
||||
|
||||
import org.hibernate.cache.spi.NaturalIdRegion;
|
||||
|
||||
/**
|
||||
* Contract for managing transactional and concurrent access to cached naturalId
|
||||
* data. For cached naturalId data, all modification actions actually just
|
||||
* invalidate the entry(s). The call sequence here is:
|
||||
* {@link #lockItem} -> {@link #remove} -> {@link #unlockItem}
|
||||
* <p/>
|
||||
* There is another usage pattern that is used to invalidate entries
|
||||
* after performing "bulk" HQL/SQL operations:
|
||||
* {@link #lockRegion} -> {@link #removeAll} -> {@link #unlockRegion}
|
||||
*
|
||||
* @author Gavin King
|
||||
* @author Steve Ebersole
|
||||
* @author Eric Dalquist
|
||||
*/
|
||||
public interface NaturalIdRegionAccessStrategy extends RegionAccessStrategy{
|
||||
|
||||
/**
|
||||
* Get the wrapped naturalId cache region
|
||||
*
|
||||
* @return The underlying region
|
||||
*/
|
||||
public NaturalIdRegion getRegion();
|
||||
}
|
|
@ -34,6 +34,7 @@ import java.util.List;
|
|||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.persistence.Basic;
|
||||
import javax.persistence.Cacheable;
|
||||
import javax.persistence.CollectionTable;
|
||||
|
@ -79,8 +80,6 @@ import javax.persistence.TableGenerator;
|
|||
import javax.persistence.UniqueConstraint;
|
||||
import javax.persistence.Version;
|
||||
|
||||
import org.jboss.logging.Logger;
|
||||
|
||||
import org.hibernate.AnnotationException;
|
||||
import org.hibernate.AssertionFailure;
|
||||
import org.hibernate.EntityMode;
|
||||
|
@ -112,6 +111,7 @@ import org.hibernate.annotations.LazyToOneOption;
|
|||
import org.hibernate.annotations.ManyToAny;
|
||||
import org.hibernate.annotations.MapKeyType;
|
||||
import org.hibernate.annotations.NaturalId;
|
||||
import org.hibernate.annotations.NaturalIdCache;
|
||||
import org.hibernate.annotations.NotFound;
|
||||
import org.hibernate.annotations.NotFoundAction;
|
||||
import org.hibernate.annotations.OnDelete;
|
||||
|
@ -167,6 +167,7 @@ import org.hibernate.mapping.SingleTableSubclass;
|
|||
import org.hibernate.mapping.Subclass;
|
||||
import org.hibernate.mapping.ToOne;
|
||||
import org.hibernate.mapping.UnionSubclass;
|
||||
import org.jboss.logging.Logger;
|
||||
|
||||
/**
|
||||
* JSR 175 annotation binder which reads the annotations from classes, applies the
|
||||
|
@ -574,6 +575,7 @@ public final class AnnotationBinder {
|
|||
entityBinder.setBatchSize( clazzToProcess.getAnnotation( BatchSize.class ) );
|
||||
entityBinder.setWhere( clazzToProcess.getAnnotation( Where.class ) );
|
||||
entityBinder.setCache( determineCacheSettings( clazzToProcess, mappings ) );
|
||||
entityBinder.setNaturalIdCache( clazzToProcess.getAnnotation( NaturalIdCache.class ) );
|
||||
|
||||
//Filters are not allowed on subclasses
|
||||
if ( !inheritanceState.hasParents() ) {
|
||||
|
|
|
@ -27,6 +27,7 @@ import java.util.HashMap;
|
|||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.persistence.Access;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.JoinColumn;
|
||||
|
@ -35,8 +36,6 @@ import javax.persistence.PrimaryKeyJoinColumn;
|
|||
import javax.persistence.SecondaryTable;
|
||||
import javax.persistence.SecondaryTables;
|
||||
|
||||
import org.jboss.logging.Logger;
|
||||
|
||||
import org.hibernate.AnnotationException;
|
||||
import org.hibernate.AssertionFailure;
|
||||
import org.hibernate.EntityMode;
|
||||
|
@ -47,6 +46,7 @@ import org.hibernate.annotations.CacheConcurrencyStrategy;
|
|||
import org.hibernate.annotations.FetchMode;
|
||||
import org.hibernate.annotations.Immutable;
|
||||
import org.hibernate.annotations.Loader;
|
||||
import org.hibernate.annotations.NaturalIdCache;
|
||||
import org.hibernate.annotations.OptimisticLockType;
|
||||
import org.hibernate.annotations.Persister;
|
||||
import org.hibernate.annotations.PolymorphismType;
|
||||
|
@ -89,6 +89,7 @@ import org.hibernate.mapping.SimpleValue;
|
|||
import org.hibernate.mapping.Table;
|
||||
import org.hibernate.mapping.TableOwner;
|
||||
import org.hibernate.mapping.Value;
|
||||
import org.jboss.logging.Logger;
|
||||
|
||||
/**
|
||||
* Stateful holder and processor for binding Entity information
|
||||
|
@ -97,7 +98,8 @@ import org.hibernate.mapping.Value;
|
|||
*/
|
||||
public class EntityBinder {
|
||||
private static final CoreMessageLogger LOG = Logger.getMessageLogger(CoreMessageLogger.class, EntityBinder.class.getName());
|
||||
|
||||
private static final String NATURAL_ID_CACHE_SUFFIX = "##NaturalId";
|
||||
|
||||
private String name;
|
||||
private XClass annotatedClass;
|
||||
private PersistentClass persistentClass;
|
||||
|
@ -119,6 +121,7 @@ public class EntityBinder {
|
|||
private java.util.Map<String, Object> secondaryTableJoins = new HashMap<String, Object>();
|
||||
private String cacheConcurrentStrategy;
|
||||
private String cacheRegion;
|
||||
private String naturalIdCacheRegion;
|
||||
private java.util.Map<String, String> filters = new HashMap<String, String>();
|
||||
private InheritanceState inheritanceState;
|
||||
private boolean ignoreIdAnnotations;
|
||||
|
@ -230,6 +233,7 @@ public class EntityBinder {
|
|||
rootClass.setCacheRegionName( cacheRegion );
|
||||
rootClass.setLazyPropertiesCacheable( cacheLazyProperty );
|
||||
}
|
||||
rootClass.setNaturalIdCacheRegionName( naturalIdCacheRegion );
|
||||
boolean forceDiscriminatorInSelects = forceDiscriminator == null
|
||||
? mappings.forceDiscriminatorInSelectsByDefault()
|
||||
: forceDiscriminator;
|
||||
|
@ -826,6 +830,25 @@ public class EntityBinder {
|
|||
cacheLazyProperty = true;
|
||||
}
|
||||
}
|
||||
|
||||
public void setNaturalIdCache(NaturalIdCache naturalIdCacheAnn) {
|
||||
if ( naturalIdCacheAnn != null ) {
|
||||
if ( BinderHelper.isEmptyAnnotationValue( naturalIdCacheAnn.region() ) ) {
|
||||
if (cacheRegion != null) {
|
||||
naturalIdCacheRegion = cacheRegion + NATURAL_ID_CACHE_SUFFIX;
|
||||
}
|
||||
else {
|
||||
naturalIdCacheRegion = persistentClass.getEntityName() + NATURAL_ID_CACHE_SUFFIX;
|
||||
}
|
||||
}
|
||||
else {
|
||||
naturalIdCacheRegion = naturalIdCacheAnn.region();
|
||||
}
|
||||
}
|
||||
else {
|
||||
naturalIdCacheRegion = null;
|
||||
}
|
||||
}
|
||||
|
||||
public static String getCacheConcurrencyStrategy(CacheConcurrencyStrategy strategy) {
|
||||
org.hibernate.cache.spi.access.AccessType accessType = strategy.toAccessType();
|
||||
|
|
|
@ -182,6 +182,14 @@ public interface SessionFactoryImplementor extends Mapping, SessionFactory {
|
|||
* @return The region
|
||||
*/
|
||||
public Region getSecondLevelCacheRegion(String regionName);
|
||||
|
||||
/**
|
||||
* Get a named naturalId cache region
|
||||
*
|
||||
* @param regionName The name of the region to retrieve.
|
||||
* @return The region
|
||||
*/
|
||||
public Region getNaturalIdCacheRegion(String regionName);
|
||||
|
||||
/**
|
||||
* Get a map of all the second level cache regions currently maintained in
|
||||
|
|
|
@ -39,11 +39,10 @@ import java.util.Properties;
|
|||
import java.util.Set;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ConcurrentMap;
|
||||
|
||||
import javax.naming.Reference;
|
||||
import javax.naming.StringRefAddr;
|
||||
|
||||
import org.jboss.logging.Logger;
|
||||
|
||||
import org.hibernate.AssertionFailure;
|
||||
import org.hibernate.Cache;
|
||||
import org.hibernate.ConnectionReleaseMode;
|
||||
|
@ -145,6 +144,7 @@ import org.hibernate.tuple.entity.EntityTuplizer;
|
|||
import org.hibernate.type.AssociationType;
|
||||
import org.hibernate.type.Type;
|
||||
import org.hibernate.type.TypeResolver;
|
||||
import org.jboss.logging.Logger;
|
||||
|
||||
|
||||
/**
|
||||
|
@ -173,7 +173,6 @@ import org.hibernate.type.TypeResolver;
|
|||
public final class SessionFactoryImpl
|
||||
implements SessionFactoryImplementor {
|
||||
|
||||
private static final String NATURAL_ID_CACHE_SUFFIX = "##NaturalId";
|
||||
private static final CoreMessageLogger LOG = Logger.getMessageLogger(CoreMessageLogger.class, SessionFactoryImpl.class.getName());
|
||||
private static final IdentifierGenerator UUID_GENERATOR = UUIDGenerator.buildSessionFactoryUniqueIdentifierGenerator();
|
||||
|
||||
|
@ -360,8 +359,8 @@ public final class SessionFactoryImpl
|
|||
entityPersisters.put( model.getEntityName(), cp );
|
||||
classMeta.put( model.getEntityName(), cp.getClassMetadata() );
|
||||
|
||||
if ( cp.hasNaturalIdentifier() && cp.isNatrualIdentifierCached() ) {
|
||||
final String naturalIdCacheRegionName = cacheRegionPrefix + model.getRootClass().getCacheRegionName() + NATURAL_ID_CACHE_SUFFIX;
|
||||
if ( cp.hasNaturalIdentifier() && model.getNaturalIdCacheRegionName() != null ) {
|
||||
final String naturalIdCacheRegionName = cacheRegionPrefix + model.getNaturalIdCacheRegionName();
|
||||
NaturalIdRegionAccessStrategy naturalIdAccessStrategy = ( NaturalIdRegionAccessStrategy ) entityAccessStrategies.get( naturalIdCacheRegionName );
|
||||
|
||||
if ( naturalIdAccessStrategy == null && settings.isSecondLevelCacheEnabled() ) {
|
||||
|
@ -805,14 +804,6 @@ public final class SessionFactoryImpl
|
|||
);
|
||||
entityPersisters.put( model.getEntity().getName(), cp );
|
||||
classMeta.put( model.getEntity().getName(), cp.getClassMetadata() );
|
||||
|
||||
if ( settings.isSecondLevelCacheEnabled() && cp.hasNaturalIdentifier() && cp.isNatrualIdentifierCached() ) {
|
||||
final String naturalIdCacheRegionName = cacheRegionPrefix + rootEntityBinding.getHierarchyDetails().getCaching().getRegion() + NATURAL_ID_CACHE_SUFFIX;
|
||||
final NaturalIdRegion naturalIdRegion = settings.getRegionFactory().buildNaturalIdRegion( naturalIdCacheRegionName, properties, CacheDataDescriptionImpl.decode( cp ) );
|
||||
final NaturalIdRegionAccessStrategy naturalIdAccessStrategy = naturalIdRegion.buildAccessStrategy( settings.getRegionFactory().getDefaultAccessType() );
|
||||
entityAccessStrategies.put( naturalIdCacheRegionName, naturalIdAccessStrategy );
|
||||
allCacheRegions.put( naturalIdCacheRegionName, naturalIdRegion );
|
||||
}
|
||||
}
|
||||
this.classMetadata = Collections.unmodifiableMap(classMeta);
|
||||
|
||||
|
@ -1643,6 +1634,10 @@ public final class SessionFactoryImpl
|
|||
return allCacheRegions.get( regionName );
|
||||
}
|
||||
|
||||
public Region getNaturalIdCacheRegion(String regionName) {
|
||||
return allCacheRegions.get( regionName );
|
||||
}
|
||||
|
||||
@SuppressWarnings( {"unchecked"})
|
||||
public Map getAllSecondLevelCacheRegions() {
|
||||
return new HashMap( allCacheRegions );
|
||||
|
|
|
@ -12,6 +12,7 @@ import org.hibernate.internal.CoreMessageLogger;
|
|||
import org.hibernate.internal.SessionFactoryRegistry;
|
||||
import org.hibernate.stat.CollectionStatistics;
|
||||
import org.hibernate.stat.EntityStatistics;
|
||||
import org.hibernate.stat.NaturalIdCacheStatistics;
|
||||
import org.hibernate.stat.QueryStatistics;
|
||||
import org.hibernate.stat.SecondLevelCacheStatistics;
|
||||
import org.hibernate.stat.Statistics;
|
||||
|
@ -227,6 +228,23 @@ public class StatisticsService implements StatisticsServiceMBean {
|
|||
public long getSecondLevelCachePutCount() {
|
||||
return stats.getSecondLevelCachePutCount();
|
||||
}
|
||||
|
||||
public NaturalIdCacheStatistics getNaturalIdCacheStatistics(String regionName) {
|
||||
return stats.getNaturalIdCacheStatistics( regionName );
|
||||
}
|
||||
|
||||
public long getNaturalIdCacheHitCount() {
|
||||
return stats.getNaturalIdCacheHitCount();
|
||||
}
|
||||
|
||||
public long getNaturalIdCacheMissCount() {
|
||||
return stats.getNaturalIdCacheMissCount();
|
||||
}
|
||||
|
||||
public long getNaturalIdCachePutCount() {
|
||||
return stats.getNaturalIdCachePutCount();
|
||||
}
|
||||
|
||||
/**
|
||||
* @see StatisticsServiceMBean#getSessionCloseCount()
|
||||
*/
|
||||
|
|
|
@ -248,6 +248,7 @@ public abstract class PersistentClass implements Serializable, Filterable, MetaA
|
|||
public abstract boolean isInherited();
|
||||
public abstract boolean isPolymorphic();
|
||||
public abstract boolean isVersioned();
|
||||
public abstract String getNaturalIdCacheRegionName();
|
||||
public abstract String getCacheConcurrencyStrategy();
|
||||
public abstract PersistentClass getSuperclass();
|
||||
public abstract boolean isExplicitPolymorphism();
|
||||
|
|
|
@ -32,6 +32,7 @@ import org.jboss.logging.Logger;
|
|||
import org.hibernate.MappingException;
|
||||
import org.hibernate.engine.spi.Mapping;
|
||||
import org.hibernate.internal.CoreMessageLogger;
|
||||
import org.hibernate.internal.SessionFactoryImpl;
|
||||
import org.hibernate.internal.util.ReflectHelper;
|
||||
import org.hibernate.internal.util.collections.SingletonIterator;
|
||||
|
||||
|
@ -52,6 +53,7 @@ public class RootClass extends PersistentClass implements TableOwner {
|
|||
private boolean polymorphic;
|
||||
private String cacheConcurrencyStrategy;
|
||||
private String cacheRegionName;
|
||||
private String naturalIdCacheRegionName;
|
||||
private boolean lazyPropertiesCacheable = true;
|
||||
private Value discriminator; //may be final
|
||||
private boolean mutable = true;
|
||||
|
@ -307,7 +309,15 @@ public class RootClass extends PersistentClass implements TableOwner {
|
|||
public void setCacheRegionName(String cacheRegionName) {
|
||||
this.cacheRegionName = cacheRegionName;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String getNaturalIdCacheRegionName() {
|
||||
return naturalIdCacheRegionName;
|
||||
}
|
||||
public void setNaturalIdCacheRegionName(String naturalIdCacheRegionName) {
|
||||
this.naturalIdCacheRegionName = naturalIdCacheRegionName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isLazyPropertiesCacheable() {
|
||||
return lazyPropertiesCacheable;
|
||||
|
|
|
@ -55,6 +55,11 @@ public class Subclass extends PersistentClass {
|
|||
return subclassId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getNaturalIdCacheRegionName() {
|
||||
return getSuperclass().getNaturalIdCacheRegionName();
|
||||
}
|
||||
|
||||
public String getCacheConcurrencyStrategy() {
|
||||
return getSuperclass().getCacheConcurrencyStrategy();
|
||||
}
|
||||
|
|
|
@ -37,8 +37,6 @@ import java.util.List;
|
|||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.jboss.logging.Logger;
|
||||
|
||||
import org.hibernate.AssertionFailure;
|
||||
import org.hibernate.EntityMode;
|
||||
import org.hibernate.FetchMode;
|
||||
|
@ -122,6 +120,7 @@ import org.hibernate.type.EntityType;
|
|||
import org.hibernate.type.Type;
|
||||
import org.hibernate.type.TypeHelper;
|
||||
import org.hibernate.type.VersionType;
|
||||
import org.jboss.logging.Logger;
|
||||
|
||||
/**
|
||||
* Basic functionality for persisting an entity via JDBC
|
||||
|
@ -4601,11 +4600,6 @@ public abstract class AbstractEntityPersister
|
|||
public boolean hasNaturalIdentifier() {
|
||||
return entityMetamodel.hasNaturalIdentifier();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isNatrualIdentifierCached() {
|
||||
return entityMetamodel.isNatrualIdentifierCached();
|
||||
}
|
||||
|
||||
public void setPropertyValue(Object object, String propertyName, Object value) {
|
||||
getEntityTuplizer().setPropertyValue( object, propertyName, value );
|
||||
|
|
|
@ -289,13 +289,6 @@ public interface EntityPersister extends OptimisticCacheSource {
|
|||
* @return True if the entity defines a natural id; false otherwise.
|
||||
*/
|
||||
public boolean hasNaturalIdentifier();
|
||||
|
||||
/**
|
||||
* Determine whether this entity's natural identifier is cacheable. {@link NaturalId#cache()}
|
||||
*
|
||||
* @return True if the natural id is cacheable, false if it is not cacheable or no natural id is defined
|
||||
*/
|
||||
public boolean isNatrualIdentifierCached();
|
||||
|
||||
/**
|
||||
* If the entity defines a natural id ({@link #hasNaturalIdentifier()}), which
|
||||
|
|
|
@ -0,0 +1,50 @@
|
|||
/*
|
||||
* 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.stat;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* NaturalId query statistics
|
||||
* <p/>
|
||||
* Note that for a cached natural id, the cache miss is equals to the db count
|
||||
*
|
||||
* @author Eric Dalquist
|
||||
*/
|
||||
public interface NaturalIdCacheStatistics extends Serializable {
|
||||
long getHitCount();
|
||||
|
||||
long getMissCount();
|
||||
|
||||
long getPutCount();
|
||||
|
||||
long getElementCountInMemory();
|
||||
|
||||
long getElementCountOnDisk();
|
||||
|
||||
long getSizeInMemory();
|
||||
|
||||
Map getEntries();
|
||||
}
|
|
@ -59,6 +59,14 @@ public interface Statistics {
|
|||
*/
|
||||
public SecondLevelCacheStatistics getSecondLevelCacheStatistics(String regionName);
|
||||
|
||||
/**
|
||||
* Natural id cache statistics per region
|
||||
*
|
||||
* @param regionName region name
|
||||
* @return NaturalIdCacheStatistics
|
||||
*/
|
||||
public NaturalIdCacheStatistics getNaturalIdCacheStatistics(String regionName);
|
||||
|
||||
/**
|
||||
* Query statistics from query string (HQL or SQL)
|
||||
*
|
||||
|
@ -123,6 +131,18 @@ public interface Statistics {
|
|||
* Get the global number of cacheable queries put in cache
|
||||
*/
|
||||
public long getQueryCachePutCount();
|
||||
/**
|
||||
* Get the global number of cached naturalId lookups successfully retrieved from cache
|
||||
*/
|
||||
public long getNaturalIdCacheHitCount();
|
||||
/**
|
||||
* Get the global number of cached naturalId lookups *not* found in cache
|
||||
*/
|
||||
public long getNaturalIdCacheMissCount();
|
||||
/**
|
||||
* Get the global number of cacheable naturalId lookups put in cache
|
||||
*/
|
||||
public long getNaturalIdCachePutCount();
|
||||
/**
|
||||
* Get the global number of timestamps successfully retrieved from cache
|
||||
*/
|
||||
|
|
|
@ -0,0 +1,112 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* 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.stat.internal;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
|
||||
import org.hibernate.cache.spi.CacheKey;
|
||||
import org.hibernate.cache.spi.Region;
|
||||
import org.hibernate.stat.NaturalIdCacheStatistics;
|
||||
|
||||
/**
|
||||
* Second level cache statistics of a specific region
|
||||
*
|
||||
* @author Alex Snaps
|
||||
*/
|
||||
public class ConcurrentNaturalIdCacheStatisticsImpl extends CategorizedStatistics implements NaturalIdCacheStatistics {
|
||||
private final transient Region region;
|
||||
private AtomicLong hitCount = new AtomicLong();
|
||||
private AtomicLong missCount = new AtomicLong();
|
||||
private AtomicLong putCount = new AtomicLong();
|
||||
|
||||
ConcurrentNaturalIdCacheStatisticsImpl(Region region) {
|
||||
super( region.getName() );
|
||||
this.region = region;
|
||||
}
|
||||
|
||||
public long getHitCount() {
|
||||
return hitCount.get();
|
||||
}
|
||||
|
||||
public long getMissCount() {
|
||||
return missCount.get();
|
||||
}
|
||||
|
||||
public long getPutCount() {
|
||||
return putCount.get();
|
||||
}
|
||||
|
||||
public long getElementCountInMemory() {
|
||||
return region.getElementCountInMemory();
|
||||
}
|
||||
|
||||
public long getElementCountOnDisk() {
|
||||
return region.getElementCountOnDisk();
|
||||
}
|
||||
|
||||
public long getSizeInMemory() {
|
||||
return region.getSizeInMemory();
|
||||
}
|
||||
|
||||
public Map getEntries() {
|
||||
Map map = new HashMap();
|
||||
Iterator iter = region.toMap().entrySet().iterator();
|
||||
while (iter.hasNext()) {
|
||||
Map.Entry me = (Map.Entry) iter.next();
|
||||
map.put(((CacheKey) me.getKey()).getKey(), me.getValue());
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
StringBuilder buf = new StringBuilder()
|
||||
.append("NaturalIdCacheStatistics")
|
||||
.append("[hitCount=").append(this.hitCount)
|
||||
.append(",missCount=").append(this.missCount)
|
||||
.append(",putCount=").append(this.putCount);
|
||||
//not sure if this would ever be null but wanted to be careful
|
||||
if (region != null) {
|
||||
buf.append(",elementCountInMemory=").append(this.getElementCountInMemory())
|
||||
.append(",elementCountOnDisk=").append(this.getElementCountOnDisk())
|
||||
.append(",sizeInMemory=").append(this.getSizeInMemory());
|
||||
}
|
||||
buf.append(']');
|
||||
return buf.toString();
|
||||
}
|
||||
|
||||
void incrementHitCount() {
|
||||
hitCount.getAndIncrement();
|
||||
}
|
||||
|
||||
void incrementMissCount() {
|
||||
missCount.getAndIncrement();
|
||||
}
|
||||
|
||||
void incrementPutCount() {
|
||||
putCount.getAndIncrement();
|
||||
}
|
||||
}
|
|
@ -27,8 +27,6 @@ import java.util.concurrent.ConcurrentHashMap;
|
|||
import java.util.concurrent.ConcurrentMap;
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
|
||||
import org.jboss.logging.Logger;
|
||||
|
||||
import org.hibernate.cache.spi.Region;
|
||||
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||
import org.hibernate.internal.CoreMessageLogger;
|
||||
|
@ -36,9 +34,11 @@ import org.hibernate.internal.util.collections.ArrayHelper;
|
|||
import org.hibernate.service.Service;
|
||||
import org.hibernate.stat.CollectionStatistics;
|
||||
import org.hibernate.stat.EntityStatistics;
|
||||
import org.hibernate.stat.NaturalIdCacheStatistics;
|
||||
import org.hibernate.stat.QueryStatistics;
|
||||
import org.hibernate.stat.SecondLevelCacheStatistics;
|
||||
import org.hibernate.stat.spi.StatisticsImplementor;
|
||||
import org.jboss.logging.Logger;
|
||||
|
||||
/**
|
||||
* Implementation of {@link org.hibernate.stat.Statistics} based on the {@link java.util.concurrent} package.
|
||||
|
@ -76,6 +76,10 @@ public class ConcurrentStatisticsImpl implements StatisticsImplementor, Service
|
|||
private AtomicLong secondLevelCacheHitCount = new AtomicLong();
|
||||
private AtomicLong secondLevelCacheMissCount = new AtomicLong();
|
||||
private AtomicLong secondLevelCachePutCount = new AtomicLong();
|
||||
|
||||
private AtomicLong naturalIdCacheHitCount = new AtomicLong();
|
||||
private AtomicLong naturalIdCacheMissCount = new AtomicLong();
|
||||
private AtomicLong naturalIdCachePutCount = new AtomicLong();
|
||||
|
||||
private AtomicLong queryExecutionCount = new AtomicLong();
|
||||
private AtomicLong queryExecutionMaxTime = new AtomicLong();
|
||||
|
@ -93,6 +97,10 @@ public class ConcurrentStatisticsImpl implements StatisticsImplementor, Service
|
|||
|
||||
private AtomicLong optimisticFailureCount = new AtomicLong();
|
||||
|
||||
/**
|
||||
* natural id cache statistics per region
|
||||
*/
|
||||
private final ConcurrentMap naturalIdCacheStatistics = new ConcurrentHashMap();
|
||||
/**
|
||||
* second level cache statistics per region
|
||||
*/
|
||||
|
@ -127,6 +135,10 @@ public class ConcurrentStatisticsImpl implements StatisticsImplementor, Service
|
|||
secondLevelCacheHitCount.set( 0 );
|
||||
secondLevelCacheMissCount.set( 0 );
|
||||
secondLevelCachePutCount.set( 0 );
|
||||
|
||||
naturalIdCacheHitCount.set( 0 );
|
||||
naturalIdCacheMissCount.set( 0 );
|
||||
naturalIdCachePutCount.set( 0 );
|
||||
|
||||
sessionCloseCount.set( 0 );
|
||||
sessionOpenCount.set( 0 );
|
||||
|
@ -282,6 +294,31 @@ public class ConcurrentStatisticsImpl implements StatisticsImplementor, Service
|
|||
collectionRemoveCount.getAndIncrement();
|
||||
( (ConcurrentCollectionStatisticsImpl) getCollectionStatistics( role ) ).incrementRemoveCount();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public NaturalIdCacheStatistics getNaturalIdCacheStatistics(String regionName) {
|
||||
ConcurrentNaturalIdCacheStatisticsImpl nics =
|
||||
(ConcurrentNaturalIdCacheStatisticsImpl) naturalIdCacheStatistics.get( regionName );
|
||||
|
||||
if ( nics == null ) {
|
||||
if ( sessionFactory == null ) {
|
||||
return null;
|
||||
}
|
||||
Region region = sessionFactory.getNaturalIdCacheRegion( regionName );
|
||||
if ( region == null ) {
|
||||
return null;
|
||||
}
|
||||
nics = new ConcurrentNaturalIdCacheStatisticsImpl( region );
|
||||
ConcurrentNaturalIdCacheStatisticsImpl previous;
|
||||
if ( ( previous = (ConcurrentNaturalIdCacheStatisticsImpl) naturalIdCacheStatistics.putIfAbsent(
|
||||
regionName, nics
|
||||
) ) != null ) {
|
||||
nics = previous;
|
||||
}
|
||||
}
|
||||
return nics;
|
||||
}
|
||||
|
||||
/**
|
||||
* Second level cache statistics per region
|
||||
|
@ -326,6 +363,24 @@ public class ConcurrentStatisticsImpl implements StatisticsImplementor, Service
|
|||
secondLevelCacheMissCount.getAndIncrement();
|
||||
( (ConcurrentSecondLevelCacheStatisticsImpl) getSecondLevelCacheStatistics( regionName ) ).incrementMissCount();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void naturalIdCachePut(String regionName) {
|
||||
naturalIdCachePutCount.getAndIncrement();
|
||||
( (ConcurrentNaturalIdCacheStatisticsImpl) getNaturalIdCacheStatistics( regionName ) ).incrementPutCount();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void naturalIdCacheHit(String regionName) {
|
||||
naturalIdCacheHitCount.getAndIncrement();
|
||||
( (ConcurrentNaturalIdCacheStatisticsImpl) getNaturalIdCacheStatistics( regionName ) ).incrementHitCount();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void naturalIdCacheMiss(String regionName) {
|
||||
naturalIdCacheMissCount.getAndIncrement();
|
||||
( (ConcurrentNaturalIdCacheStatisticsImpl) getNaturalIdCacheStatistics( regionName ) ).incrementMissCount();
|
||||
}
|
||||
|
||||
@SuppressWarnings({ "UnnecessaryBoxing" })
|
||||
public void queryExecuted(String hql, int rows, long time) {
|
||||
|
@ -515,6 +570,21 @@ public class ConcurrentStatisticsImpl implements StatisticsImplementor, Service
|
|||
public long getSecondLevelCachePutCount() {
|
||||
return secondLevelCachePutCount.get();
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getNaturalIdCacheHitCount() {
|
||||
return naturalIdCacheHitCount.get();
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getNaturalIdCacheMissCount() {
|
||||
return naturalIdCacheMissCount.get();
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getNaturalIdCachePutCount() {
|
||||
return naturalIdCachePutCount.get();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return session closing
|
||||
|
|
|
@ -25,6 +25,7 @@ package org.hibernate.stat.spi;
|
|||
|
||||
import org.hibernate.service.Service;
|
||||
import org.hibernate.stat.Statistics;
|
||||
import org.hibernate.stat.internal.ConcurrentSecondLevelCacheStatisticsImpl;
|
||||
|
||||
/**
|
||||
* Statistics SPI for the Hibernate core. This is essentially the "statistic collector" API, its the contract
|
||||
|
@ -171,6 +172,27 @@ public interface StatisticsImplementor extends Statistics, Service {
|
|||
* @param regionName The name of the cache region
|
||||
*/
|
||||
public void secondLevelCacheMiss(String regionName);
|
||||
|
||||
/**
|
||||
* Callback indicating a put into natural id cache.
|
||||
*
|
||||
* @param regionName The name of the cache region
|
||||
*/
|
||||
public void naturalIdCachePut(String regionName);
|
||||
|
||||
/**
|
||||
* Callback indicating a get from natural id cache resulted in a hit.
|
||||
*
|
||||
* @param regionName The name of the cache region
|
||||
*/
|
||||
public void naturalIdCacheHit(String regionName);
|
||||
|
||||
/**
|
||||
* Callback indicating a get from natural id cache resulted in a miss.
|
||||
*
|
||||
* @param regionName The name of the cache region
|
||||
*/
|
||||
public void naturalIdCacheMiss(String regionName);
|
||||
|
||||
/**
|
||||
* Callback indicating a put into the query cache.
|
||||
|
|
|
@ -263,7 +263,7 @@ public class EntityMetamodel implements Serializable {
|
|||
else {
|
||||
naturalIdPropertyNumbers = ArrayHelper.toIntArray(naturalIdNumbers);
|
||||
hasImmutableNaturalId = !foundUpdateableNaturalIdProperty;
|
||||
hasCacheableNaturalId = true; //TODO how to read the annotation here?
|
||||
hasCacheableNaturalId = persistentClass.getNaturalIdCacheRegionName() != null;
|
||||
}
|
||||
|
||||
hasInsertGeneratedValues = foundInsertGeneratedValue;
|
||||
|
@ -510,7 +510,7 @@ public class EntityMetamodel implements Serializable {
|
|||
else {
|
||||
naturalIdPropertyNumbers = ArrayHelper.toIntArray(naturalIdNumbers);
|
||||
hasImmutableNaturalId = !foundUpdateableNaturalIdProperty;
|
||||
hasCacheableNaturalId = true; //TODO how to read the annotation here?
|
||||
hasCacheableNaturalId = false; //See previous TODO and HHH-6354
|
||||
}
|
||||
|
||||
hasInsertGeneratedValues = foundInsertGeneratedValue;
|
||||
|
|
|
@ -23,11 +23,14 @@
|
|||
*/
|
||||
package org.hibernate.test.annotations.naturalid;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import org.hibernate.Criteria;
|
||||
import org.hibernate.NaturalIdLoadAccess;
|
||||
import org.hibernate.Session;
|
||||
import org.hibernate.Transaction;
|
||||
import org.hibernate.cfg.Configuration;
|
||||
|
@ -35,9 +38,7 @@ import org.hibernate.criterion.Restrictions;
|
|||
import org.hibernate.metadata.ClassMetadata;
|
||||
import org.hibernate.stat.Statistics;
|
||||
import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import org.junit.Test;
|
||||
|
||||
/**
|
||||
* Test case for NaturalId annotation
|
||||
|
@ -112,6 +113,53 @@ public class NaturalIdTest extends BaseCoreFunctionalTestCase {
|
|||
s.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNaturalIdLoaderCached() {
|
||||
saveSomeCitizens();
|
||||
|
||||
Session s = openSession();
|
||||
Transaction tx = s.beginTransaction();
|
||||
State france = ( State ) s.load( State.class, 2 );
|
||||
final NaturalIdLoadAccess naturalIdLoader = s.byNaturalId( Citizen.class );
|
||||
naturalIdLoader.using( "ssn", "1234" ).using( "state", france );
|
||||
|
||||
Statistics stats = sessionFactory().getStatistics();
|
||||
stats.setStatisticsEnabled( true );
|
||||
stats.clear();
|
||||
assertEquals(
|
||||
"Cache hits should be empty", 0, stats
|
||||
.getQueryCacheHitCount()
|
||||
);
|
||||
|
||||
// first query
|
||||
Citizen citizen = (Citizen)naturalIdLoader.load();
|
||||
assertNotNull( citizen );
|
||||
assertEquals(
|
||||
"Cache hits should be empty", 0, stats
|
||||
.getNaturalIdCacheHitCount()
|
||||
);
|
||||
assertEquals(
|
||||
"First load should be a miss", 1, stats
|
||||
.getNaturalIdCacheMissCount()
|
||||
);
|
||||
assertEquals(
|
||||
"Query result should be added to cache", 1, stats
|
||||
.getNaturalIdCachePutCount()
|
||||
);
|
||||
|
||||
// query a second time - result should be cached
|
||||
citizen = (Citizen)naturalIdLoader.load();
|
||||
assertNotNull( citizen );
|
||||
assertEquals(
|
||||
"Cache hits should be empty", 1, stats
|
||||
.getNaturalIdCacheHitCount()
|
||||
);
|
||||
|
||||
// cleanup
|
||||
tx.rollback();
|
||||
s.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNaturalIdUncached() {
|
||||
saveSomeCitizens();
|
||||
|
|
|
@ -235,11 +235,6 @@ public class GoofyPersisterClassProvider implements PersisterClassResolver {
|
|||
public boolean hasNaturalIdentifier() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isNatrualIdentifierCached() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int[] getNaturalIdentifierProperties() {
|
||||
|
|
|
@ -563,11 +563,6 @@ public class CustomPersister implements EntityPersister {
|
|||
public boolean hasNaturalIdentifier() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isNatrualIdentifierCached() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasMutableProperties() {
|
||||
|
|
|
@ -0,0 +1,227 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* 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.ehcache.internal.nonstop;
|
||||
|
||||
import net.sf.ehcache.constructs.nonstop.NonStopCacheException;
|
||||
|
||||
import org.hibernate.cache.CacheException;
|
||||
import org.hibernate.cache.spi.NaturalIdRegion;
|
||||
import org.hibernate.cache.spi.access.NaturalIdRegionAccessStrategy;
|
||||
import org.hibernate.cache.spi.access.SoftLock;
|
||||
|
||||
/**
|
||||
* Implementation of {@link NaturalIdRegionAccessStrategy} that handles {@link NonStopCacheException} using
|
||||
* {@link HibernateNonstopCacheExceptionHandler}
|
||||
*
|
||||
* @author Abhishek Sanoujam
|
||||
* @author Alex Snaps
|
||||
*/
|
||||
public class NonstopAwareNaturalIdRegionAccessStrategy implements NaturalIdRegionAccessStrategy {
|
||||
|
||||
private final NaturalIdRegionAccessStrategy actualStrategy;
|
||||
private final HibernateNonstopCacheExceptionHandler hibernateNonstopExceptionHandler;
|
||||
|
||||
/**
|
||||
* Constructor accepting the actual {@link NaturalIdRegionAccessStrategy} and the {@link HibernateNonstopCacheExceptionHandler}
|
||||
*
|
||||
* @param actualStrategy
|
||||
* @param hibernateNonstopExceptionHandler
|
||||
*/
|
||||
public NonstopAwareNaturalIdRegionAccessStrategy(NaturalIdRegionAccessStrategy actualStrategy,
|
||||
HibernateNonstopCacheExceptionHandler hibernateNonstopExceptionHandler) {
|
||||
this.actualStrategy = actualStrategy;
|
||||
this.hibernateNonstopExceptionHandler = hibernateNonstopExceptionHandler;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* @see org.hibernate.cache.spi.access.EntityRegionAccessStrategy#getRegion()
|
||||
*/
|
||||
public NaturalIdRegion getRegion() {
|
||||
return actualStrategy.getRegion();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* @see org.hibernate.cache.spi.access.EntityRegionAccessStrategy#evict(java.lang.Object)
|
||||
*/
|
||||
public void evict(Object key) throws CacheException {
|
||||
try {
|
||||
actualStrategy.evict( key );
|
||||
}
|
||||
catch ( NonStopCacheException nonStopCacheException ) {
|
||||
hibernateNonstopExceptionHandler.handleNonstopCacheException( nonStopCacheException );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* @see org.hibernate.cache.spi.access.EntityRegionAccessStrategy#evictAll()
|
||||
*/
|
||||
public void evictAll() throws CacheException {
|
||||
try {
|
||||
actualStrategy.evictAll();
|
||||
}
|
||||
catch ( NonStopCacheException nonStopCacheException ) {
|
||||
hibernateNonstopExceptionHandler.handleNonstopCacheException( nonStopCacheException );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* @see org.hibernate.cache.spi.access.EntityRegionAccessStrategy#get(java.lang.Object, long)
|
||||
*/
|
||||
public Object get(Object key, long txTimestamp) throws CacheException {
|
||||
try {
|
||||
return actualStrategy.get( key, txTimestamp );
|
||||
}
|
||||
catch ( NonStopCacheException nonStopCacheException ) {
|
||||
hibernateNonstopExceptionHandler.handleNonstopCacheException( nonStopCacheException );
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* @see org.hibernate.cache.spi.access.EntityRegionAccessStrategy#lockItem(java.lang.Object, java.lang.Object)
|
||||
*/
|
||||
public SoftLock lockItem(Object key, Object version) throws CacheException {
|
||||
try {
|
||||
return actualStrategy.lockItem( key, version );
|
||||
}
|
||||
catch ( NonStopCacheException nonStopCacheException ) {
|
||||
hibernateNonstopExceptionHandler.handleNonstopCacheException( nonStopCacheException );
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* @see org.hibernate.cache.spi.access.EntityRegionAccessStrategy#lockRegion()
|
||||
*/
|
||||
public SoftLock lockRegion() throws CacheException {
|
||||
try {
|
||||
return actualStrategy.lockRegion();
|
||||
}
|
||||
catch ( NonStopCacheException nonStopCacheException ) {
|
||||
hibernateNonstopExceptionHandler.handleNonstopCacheException( nonStopCacheException );
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* @see org.hibernate.cache.spi.access.EntityRegionAccessStrategy#putFromLoad(java.lang.Object, java.lang.Object, long, java.lang.Object,
|
||||
* boolean)
|
||||
*/
|
||||
public boolean putFromLoad(Object key, Object value, long txTimestamp, Object version, boolean minimalPutOverride)
|
||||
throws CacheException {
|
||||
try {
|
||||
return actualStrategy.putFromLoad( key, value, txTimestamp, version, minimalPutOverride );
|
||||
}
|
||||
catch ( NonStopCacheException nonStopCacheException ) {
|
||||
hibernateNonstopExceptionHandler.handleNonstopCacheException( nonStopCacheException );
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* @see org.hibernate.cache.spi.access.EntityRegionAccessStrategy#putFromLoad(java.lang.Object, java.lang.Object, long, java.lang.Object)
|
||||
*/
|
||||
public boolean putFromLoad(Object key, Object value, long txTimestamp, Object version) throws CacheException {
|
||||
try {
|
||||
return actualStrategy.putFromLoad( key, value, txTimestamp, version );
|
||||
}
|
||||
catch ( NonStopCacheException nonStopCacheException ) {
|
||||
hibernateNonstopExceptionHandler.handleNonstopCacheException( nonStopCacheException );
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* @see org.hibernate.cache.spi.access.EntityRegionAccessStrategy#remove(java.lang.Object)
|
||||
*/
|
||||
public void remove(Object key) throws CacheException {
|
||||
try {
|
||||
actualStrategy.remove( key );
|
||||
}
|
||||
catch ( NonStopCacheException nonStopCacheException ) {
|
||||
hibernateNonstopExceptionHandler.handleNonstopCacheException( nonStopCacheException );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* @see org.hibernate.cache.spi.access.EntityRegionAccessStrategy#removeAll()
|
||||
*/
|
||||
public void removeAll() throws CacheException {
|
||||
try {
|
||||
actualStrategy.removeAll();
|
||||
}
|
||||
catch ( NonStopCacheException nonStopCacheException ) {
|
||||
hibernateNonstopExceptionHandler.handleNonstopCacheException( nonStopCacheException );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* @see org.hibernate.cache.spi.access.EntityRegionAccessStrategy#unlockItem(java.lang.Object, org.hibernate.cache.spi.access.SoftLock)
|
||||
*/
|
||||
public void unlockItem(Object key, SoftLock lock) throws CacheException {
|
||||
try {
|
||||
actualStrategy.unlockItem( key, lock );
|
||||
}
|
||||
catch ( NonStopCacheException nonStopCacheException ) {
|
||||
hibernateNonstopExceptionHandler.handleNonstopCacheException( nonStopCacheException );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* @see org.hibernate.cache.spi.access.EntityRegionAccessStrategy#unlockRegion(org.hibernate.cache.spi.access.SoftLock)
|
||||
*/
|
||||
public void unlockRegion(SoftLock lock) throws CacheException {
|
||||
try {
|
||||
actualStrategy.unlockRegion( lock );
|
||||
}
|
||||
catch ( NonStopCacheException nonStopCacheException ) {
|
||||
hibernateNonstopExceptionHandler.handleNonstopCacheException( nonStopCacheException );
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,66 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* 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.ehcache.internal.regions;
|
||||
|
||||
import java.util.Properties;
|
||||
|
||||
import net.sf.ehcache.Ehcache;
|
||||
|
||||
import org.hibernate.cache.CacheException;
|
||||
import org.hibernate.cache.ehcache.internal.strategy.EhcacheAccessStrategyFactory;
|
||||
import org.hibernate.cache.spi.CacheDataDescription;
|
||||
import org.hibernate.cache.spi.NaturalIdRegion;
|
||||
import org.hibernate.cache.spi.access.AccessType;
|
||||
import org.hibernate.cache.spi.access.NaturalIdRegionAccessStrategy;
|
||||
import org.hibernate.cfg.Settings;
|
||||
|
||||
/**
|
||||
* A collection region specific wrapper around an Ehcache instance.
|
||||
* <p/>
|
||||
* This implementation returns Ehcache specific access strategy instances for all the non-transactional access types. Transactional access
|
||||
* is not supported.
|
||||
*
|
||||
* @author Chris Dennis
|
||||
* @author Abhishek Sanoujam
|
||||
* @author Alex Snaps
|
||||
*/
|
||||
public class EhcacheNaturalIdRegion extends EhcacheTransactionalDataRegion implements NaturalIdRegion {
|
||||
|
||||
|
||||
/**
|
||||
* Constructs an EhcacheNaturalIdRegion around the given underlying cache.
|
||||
*
|
||||
* @param accessStrategyFactory
|
||||
*/
|
||||
public EhcacheNaturalIdRegion(EhcacheAccessStrategyFactory accessStrategyFactory, Ehcache underlyingCache, Settings settings,
|
||||
CacheDataDescription metadata, Properties properties) {
|
||||
super( accessStrategyFactory, underlyingCache, settings, metadata, properties );
|
||||
}
|
||||
|
||||
@Override
|
||||
public NaturalIdRegionAccessStrategy buildAccessStrategy(AccessType accessType) throws CacheException {
|
||||
return accessStrategyFactory.createNaturalIdRegionAccessStrategy( this, accessType );
|
||||
}
|
||||
}
|
|
@ -0,0 +1,99 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* 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.ehcache.internal.strategy;
|
||||
|
||||
import org.hibernate.cache.CacheException;
|
||||
import org.hibernate.cache.ehcache.internal.regions.EhcacheNaturalIdRegion;
|
||||
import org.hibernate.cache.spi.NaturalIdRegion;
|
||||
import org.hibernate.cache.spi.access.NaturalIdRegionAccessStrategy;
|
||||
import org.hibernate.cache.spi.access.SoftLock;
|
||||
import org.hibernate.cfg.Settings;
|
||||
|
||||
/**
|
||||
* Ehcache specific non-strict read/write NaturalId region access strategy
|
||||
*
|
||||
* @author Chris Dennis
|
||||
* @author Alex Snaps
|
||||
*/
|
||||
public class NonStrictReadWriteEhcacheNaturalIdRegionAccessStrategy
|
||||
extends AbstractEhcacheAccessStrategy<EhcacheNaturalIdRegion>
|
||||
implements NaturalIdRegionAccessStrategy {
|
||||
|
||||
/**
|
||||
* Create a non-strict read/write access strategy accessing the given NaturalId region.
|
||||
*/
|
||||
public NonStrictReadWriteEhcacheNaturalIdRegionAccessStrategy(EhcacheNaturalIdRegion region, Settings settings) {
|
||||
super( region, settings );
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public NaturalIdRegion getRegion() {
|
||||
return region;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public Object get(Object key, long txTimestamp) throws CacheException {
|
||||
return region.get( key );
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public boolean putFromLoad(Object key, Object value, long txTimestamp, Object version, boolean minimalPutOverride)
|
||||
throws CacheException {
|
||||
if ( minimalPutOverride && region.contains( key ) ) {
|
||||
return false;
|
||||
}
|
||||
else {
|
||||
region.put( key, value );
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Since this is a non-strict read/write strategy item locking is not used.
|
||||
*/
|
||||
public SoftLock lockItem(Object key, Object version) throws CacheException {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Since this is a non-strict read/write strategy item locking is not used.
|
||||
*/
|
||||
public void unlockItem(Object key, SoftLock lock) throws CacheException {
|
||||
region.remove( key );
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public void remove(Object key) throws CacheException {
|
||||
region.remove( key );
|
||||
}
|
||||
}
|
|
@ -0,0 +1,93 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* 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.ehcache.internal.strategy;
|
||||
|
||||
import org.hibernate.cache.CacheException;
|
||||
import org.hibernate.cache.ehcache.internal.regions.EhcacheNaturalIdRegion;
|
||||
import org.hibernate.cache.spi.NaturalIdRegion;
|
||||
import org.hibernate.cache.spi.access.NaturalIdRegionAccessStrategy;
|
||||
import org.hibernate.cache.spi.access.SoftLock;
|
||||
import org.hibernate.cfg.Settings;
|
||||
|
||||
/**
|
||||
* Ehcache specific read-only NaturalId region access strategy
|
||||
*
|
||||
* @author Chris Dennis
|
||||
* @author Alex Snaps
|
||||
*/
|
||||
public class ReadOnlyEhcacheNaturalIdRegionAccessStrategy
|
||||
extends AbstractEhcacheAccessStrategy<EhcacheNaturalIdRegion>
|
||||
implements NaturalIdRegionAccessStrategy {
|
||||
|
||||
/**
|
||||
* Create a read-only access strategy accessing the given NaturalId region.
|
||||
*/
|
||||
public ReadOnlyEhcacheNaturalIdRegionAccessStrategy(EhcacheNaturalIdRegion region, Settings settings) {
|
||||
super( region, settings );
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public NaturalIdRegion getRegion() {
|
||||
return region;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public Object get(Object key, long txTimestamp) throws CacheException {
|
||||
return region.get( key );
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public boolean putFromLoad(Object key, Object value, long txTimestamp, Object version, boolean minimalPutOverride)
|
||||
throws CacheException {
|
||||
if ( minimalPutOverride && region.contains( key ) ) {
|
||||
return false;
|
||||
}
|
||||
else {
|
||||
region.put( key, value );
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Throws UnsupportedOperationException since this cache is read-only
|
||||
*
|
||||
* @throws UnsupportedOperationException always
|
||||
*/
|
||||
public SoftLock lockItem(Object key, Object version) throws UnsupportedOperationException {
|
||||
throw new UnsupportedOperationException( "Can't write to a readonly object" );
|
||||
}
|
||||
|
||||
/**
|
||||
* A no-op since this cache is read-only
|
||||
*/
|
||||
public void unlockItem(Object key, SoftLock lock) throws CacheException {
|
||||
//throw new UnsupportedOperationException("Can't write to a readonly object");
|
||||
}
|
||||
}
|
|
@ -0,0 +1,54 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* 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.ehcache.internal.strategy;
|
||||
|
||||
import org.hibernate.cache.ehcache.internal.regions.EhcacheNaturalIdRegion;
|
||||
import org.hibernate.cache.spi.NaturalIdRegion;
|
||||
import org.hibernate.cache.spi.access.NaturalIdRegionAccessStrategy;
|
||||
import org.hibernate.cfg.Settings;
|
||||
|
||||
/**
|
||||
* Ehcache specific read/write NaturalId region access strategy
|
||||
*
|
||||
* @author Chris Dennis
|
||||
* @author Alex Snaps
|
||||
*/
|
||||
public class ReadWriteEhcacheNaturalIdRegionAccessStrategy
|
||||
extends AbstractReadWriteEhcacheAccessStrategy<EhcacheNaturalIdRegion>
|
||||
implements NaturalIdRegionAccessStrategy {
|
||||
|
||||
/**
|
||||
* Create a read/write access strategy accessing the given NaturalId region.
|
||||
*/
|
||||
public ReadWriteEhcacheNaturalIdRegionAccessStrategy(EhcacheNaturalIdRegion region, Settings settings) {
|
||||
super( region, settings );
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public NaturalIdRegion getRegion() {
|
||||
return region;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,127 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* 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.ehcache.internal.strategy;
|
||||
|
||||
import net.sf.ehcache.Ehcache;
|
||||
import net.sf.ehcache.Element;
|
||||
|
||||
import org.hibernate.cache.CacheException;
|
||||
import org.hibernate.cache.ehcache.internal.regions.EhcacheNaturalIdRegion;
|
||||
import org.hibernate.cache.spi.NaturalIdRegion;
|
||||
import org.hibernate.cache.spi.access.NaturalIdRegionAccessStrategy;
|
||||
import org.hibernate.cache.spi.access.SoftLock;
|
||||
import org.hibernate.cfg.Settings;
|
||||
|
||||
/**
|
||||
* JTA NaturalIdRegionAccessStrategy.
|
||||
*
|
||||
* @author Chris Dennis
|
||||
* @author Ludovic Orban
|
||||
* @author Alex Snaps
|
||||
*/
|
||||
public class TransactionalEhcacheNaturalIdRegionAccessStrategy
|
||||
extends AbstractEhcacheAccessStrategy<EhcacheNaturalIdRegion>
|
||||
implements NaturalIdRegionAccessStrategy {
|
||||
|
||||
private final Ehcache ehcache;
|
||||
|
||||
/**
|
||||
* Construct a new collection region access strategy.
|
||||
*
|
||||
* @param region the Hibernate region.
|
||||
* @param ehcache the cache.
|
||||
* @param settings the Hibernate settings.
|
||||
*/
|
||||
public TransactionalEhcacheNaturalIdRegionAccessStrategy(EhcacheNaturalIdRegion region, Ehcache ehcache, Settings settings) {
|
||||
super( region, settings );
|
||||
this.ehcache = ehcache;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public Object get(Object key, long txTimestamp) throws CacheException {
|
||||
try {
|
||||
Element element = ehcache.get( key );
|
||||
return element == null ? null : element.getObjectValue();
|
||||
}
|
||||
catch ( net.sf.ehcache.CacheException e ) {
|
||||
throw new CacheException( e );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public NaturalIdRegion getRegion() {
|
||||
return region;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public SoftLock lockItem(Object key, Object version) throws CacheException {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public boolean putFromLoad(Object key, Object value, long txTimestamp,
|
||||
Object version, boolean minimalPutOverride) throws CacheException {
|
||||
try {
|
||||
if ( minimalPutOverride && ehcache.get( key ) != null ) {
|
||||
return false;
|
||||
}
|
||||
//OptimisticCache? versioning?
|
||||
ehcache.put( new Element( key, value ) );
|
||||
return true;
|
||||
}
|
||||
catch ( net.sf.ehcache.CacheException e ) {
|
||||
throw new CacheException( e );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public void remove(Object key) throws CacheException {
|
||||
try {
|
||||
ehcache.remove( key );
|
||||
}
|
||||
catch ( net.sf.ehcache.CacheException e ) {
|
||||
throw new CacheException( e );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public void unlockItem(Object key, SoftLock lock) throws CacheException {
|
||||
// no-op
|
||||
}
|
||||
|
||||
}
|
|
@ -258,11 +258,6 @@ public class PersisterClassProviderTest {
|
|||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isNatrualIdentifierCached() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int[] getNaturalIdentifierProperties() {
|
||||
return new int[0];
|
||||
|
|
|
@ -0,0 +1,53 @@
|
|||
/*
|
||||
* 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.hibernate.cache.spi.NaturalIdRegion;
|
||||
import org.hibernate.cache.spi.access.NaturalIdRegionAccessStrategy;
|
||||
|
||||
/**
|
||||
* @author Eric Dalquist
|
||||
*/
|
||||
class BaseNaturalIdRegionAccessStrategy extends BaseRegionAccessStrategy implements NaturalIdRegionAccessStrategy {
|
||||
private final NaturalIdRegionImpl region;
|
||||
|
||||
@Override
|
||||
protected BaseGeneralDataRegion getInternalRegion() {
|
||||
return region;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isDefaultMinimalPutOverride() {
|
||||
return region.getSettings().isMinimalPutsEnabled();
|
||||
}
|
||||
|
||||
@Override
|
||||
public NaturalIdRegion getRegion() {
|
||||
return region;
|
||||
}
|
||||
|
||||
BaseNaturalIdRegionAccessStrategy(NaturalIdRegionImpl region) {
|
||||
this.region = region;
|
||||
}
|
||||
}
|
73
hibernate-testing/src/main/java/org/hibernate/testing/cache/NaturalIdRegionImpl.java
vendored
Normal file
73
hibernate-testing/src/main/java/org/hibernate/testing/cache/NaturalIdRegionImpl.java
vendored
Normal file
|
@ -0,0 +1,73 @@
|
|||
/*
|
||||
* 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.hibernate.cache.CacheException;
|
||||
import org.hibernate.cache.spi.CacheDataDescription;
|
||||
import org.hibernate.cache.spi.NaturalIdRegion;
|
||||
import org.hibernate.cache.spi.access.AccessType;
|
||||
import org.hibernate.cache.spi.access.NaturalIdRegionAccessStrategy;
|
||||
import org.hibernate.cfg.Settings;
|
||||
import org.hibernate.internal.CoreMessageLogger;
|
||||
import org.jboss.logging.Logger;
|
||||
|
||||
/**
|
||||
* @author Eric Dalquist
|
||||
*/
|
||||
class NaturalIdRegionImpl extends BaseTransactionalDataRegion implements NaturalIdRegion {
|
||||
private static final CoreMessageLogger LOG = Logger.getMessageLogger(
|
||||
CoreMessageLogger.class, NaturalIdRegionImpl.class.getName()
|
||||
);
|
||||
private final Settings settings;
|
||||
NaturalIdRegionImpl(String name, CacheDataDescription metadata, Settings settings) {
|
||||
super( name, metadata );
|
||||
this.settings=settings;
|
||||
}
|
||||
|
||||
public Settings getSettings() {
|
||||
return settings;
|
||||
}
|
||||
|
||||
@Override
|
||||
public NaturalIdRegionAccessStrategy 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 ReadOnlyNaturalIdRegionAccessStrategy( this );
|
||||
case READ_WRITE:
|
||||
return new ReadWriteNaturalIdRegionAccessStrategy( this );
|
||||
case NONSTRICT_READ_WRITE:
|
||||
return new NonstrictReadWriteNaturalIdRegionAccessStrategy( this );
|
||||
case TRANSACTIONAL:
|
||||
return new TransactionalNaturalIdRegionAccessStrategy( this );
|
||||
// throw new UnsupportedOperationException( "doesn't support this access strategy" );
|
||||
default:
|
||||
throw new IllegalArgumentException( "unrecognized access strategy type [" + accessType + "]" );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,45 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* 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.hibernate.cache.CacheException;
|
||||
import org.hibernate.cache.spi.access.SoftLock;
|
||||
|
||||
/**
|
||||
* @author Eric Dalquist
|
||||
*/
|
||||
class NonstrictReadWriteNaturalIdRegionAccessStrategy extends BaseNaturalIdRegionAccessStrategy {
|
||||
NonstrictReadWriteNaturalIdRegionAccessStrategy(NaturalIdRegionImpl region) {
|
||||
super( region );
|
||||
}
|
||||
@Override
|
||||
public void unlockItem(Object key, SoftLock lock) throws CacheException {
|
||||
evict( key );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void remove(Object key) throws CacheException {
|
||||
evict( key );
|
||||
}
|
||||
}
|
|
@ -0,0 +1,57 @@
|
|||
/*
|
||||
* 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 Eric Dalquist
|
||||
*/
|
||||
class ReadOnlyNaturalIdRegionAccessStrategy extends BaseNaturalIdRegionAccessStrategy {
|
||||
private static final CoreMessageLogger LOG = Logger.getMessageLogger(
|
||||
CoreMessageLogger.class, ReadOnlyNaturalIdRegionAccessStrategy.class.getName()
|
||||
);
|
||||
|
||||
ReadOnlyNaturalIdRegionAccessStrategy(NaturalIdRegionImpl 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" );
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,62 @@
|
|||
/*
|
||||
* 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.spi.NaturalIdRegion;
|
||||
import org.hibernate.cache.spi.access.NaturalIdRegionAccessStrategy;
|
||||
|
||||
/**
|
||||
* @author Eric Dalquist
|
||||
*/
|
||||
class ReadWriteNaturalIdRegionAccessStrategy extends AbstractReadWriteAccessStrategy
|
||||
implements NaturalIdRegionAccessStrategy {
|
||||
|
||||
private final NaturalIdRegionImpl region;
|
||||
|
||||
ReadWriteNaturalIdRegionAccessStrategy(NaturalIdRegionImpl 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 NaturalIdRegion getRegion() {
|
||||
return region;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
package org.hibernate.testing.cache;
|
||||
|
||||
import org.hibernate.cache.CacheException;
|
||||
|
||||
/**
|
||||
* @author Eric Dalquist
|
||||
*/
|
||||
class TransactionalNaturalIdRegionAccessStrategy extends BaseNaturalIdRegionAccessStrategy {
|
||||
TransactionalNaturalIdRegionAccessStrategy(NaturalIdRegionImpl region) {
|
||||
super( region );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public void remove(Object key) throws CacheException {
|
||||
evict( key );
|
||||
}
|
||||
|
||||
|
||||
}
|
Loading…
Reference in New Issue