From abf3360b494066f40836f040eef1716db0e6f118 Mon Sep 17 00:00:00 2001 From: Gavin Date: Tue, 11 Jan 2022 14:01:47 +0100 Subject: [PATCH] improve Javadoc for Cache and fix some warnings --- .../src/main/java/org/hibernate/Cache.java | 161 +++++++++++------- .../cache/internal/DisabledCaching.java | 18 +- .../cache/internal/EnabledCaching.java | 24 +-- .../hibernate/cache/spi/CacheImplementor.java | 12 +- .../cache/spi/DirectAccessRegion.java | 7 +- .../spi/access/CachedDomainDataAccess.java | 6 +- .../stat/internal/StatisticsImpl.java | 5 +- 7 files changed, 136 insertions(+), 97 deletions(-) diff --git a/hibernate-core/src/main/java/org/hibernate/Cache.java b/hibernate-core/src/main/java/org/hibernate/Cache.java index de9dbd9798..f3eb1fadcb 100644 --- a/hibernate-core/src/main/java/org/hibernate/Cache.java +++ b/hibernate-core/src/main/java/org/hibernate/Cache.java @@ -9,18 +9,50 @@ package org.hibernate; import java.io.Serializable; /** - * Provides an API for querying/managing the second level cache regions. - *

- * CAUTION: None of these methods respect any isolation or transactional - * semantics associated with the underlying caches. Specifically, evictions - * perform an immediate "hard" removal outside any transactions and/or locking - * scheme(s). + * An API for directly querying and managing the second level cache. + *

+ * Note that only entities and collection roles explicitly annotated + * {@link jakarta.persistence.Cacheable} or {@link org.hibernate.annotations.Cache} + * are eligible for storage in the second-level cache, and so by default the state + * of an entity is always retrieved from the database when requested. + *

+ * Hibernate segments the second-level cache into named regions, one for + * each mapped entity hierarchy or collection role, each with its own policies for + * expiry, persistence, and replication, which must be configured externally to + * Hibernate. An entity hierarchy or collection role may be explicitly assigned a + * region using the {@link org.hibernate.annotations.Cache} annotation, but, by + * default, the region name is just the name of the entity class or collection role. + *

+ * The appropriate policies depend on the kind of data an entity represents. For + * example, a program might have different caching policies for "reference" data, + * for transactional data, and for data used for analytics. Ordinarily, the + * implementation of those policies is the responsibility of the + * {@linkplain org.hibernate.cache.spi.RegionFactory cache provider} and is + * transparent to code which makes use of a Hibernate {@link Session}. At worst, + * interaction with the cache may be controlled by specification of an explicit + * {@link CacheMode}. + *

+ * Very occasionally, it's necessary or advantageous to control the cache explicitly + * via programmatic eviction, using, for example, {@link #evictEntityData(Class)} to + * evicts a whole cache region, or {@link #evictEntityData(Class, Object)}, to evict + * a single item. + *

+ * If multiple entities or roles are mapped to the same cache region, they share + * policies and even the same FIFO-type expiry queue (if any). This sounds useful, + * but comes with the downside that {@link #evictEntityData(Class)} for any one of + * the entities evicts all entities mapped to the same region. It's + * therefore much more common to have a distinct region for each entity and role. + *

+ * None of the operations of this interface respect any isolation or transactional + * semantics associated with the underlying caches. In particular, eviction via + * the methods of this interface causes an immediate "hard" removal outside any + * current transaction and/or locking scheme. * * @author Steve Ebersole */ public interface Cache extends jakarta.persistence.Cache { /** - * Access to the SessionFactory this Cache is bound to. + * The {@link SessionFactory} to which this {@code Cache} belongs. * * @return The SessionFactory */ @@ -32,12 +64,10 @@ public interface Cache extends jakarta.persistence.Cache { // Entity data /** - * Determine whether the cache contains data for the given entity "instance". - *

- * The semantic here is whether the cache contains data visible for the - * current call context. + * Determine whether the cache contains an item for the entity of the given + * type, and with the given identifier. * - * @param entityClass The entity class. + * @param entityClass The entity type * @param identifier The entity identifier * * @return True if the underlying cache contains corresponding data; false @@ -46,12 +76,10 @@ public interface Cache extends jakarta.persistence.Cache { boolean containsEntity(Class entityClass, Object identifier); /** - * Determine whether the cache contains data for the given entity "instance". - *

- * The semantic here is whether the cache contains data visible for the - * current call context. + * Determine whether the cache contains an item for the entity of the type + * with the given name, and with the given identifier. * - * @param entityName The entity name. + * @param entityName The entity name * @param identifier The entity identifier * * @return True if the underlying cache contains corresponding data; false otherwise. @@ -59,9 +87,10 @@ public interface Cache extends jakarta.persistence.Cache { boolean containsEntity(String entityName, Object identifier); /** - * Evicts the entity data for a particular entity "instance". + * Evicts the cached item for the entity of the given type, and with the + * given identifier, if there is any such item in the cache. * - * @param entityClass The entity class. + * @param entityClass The entity type * @param identifier The entity identifier * * @since 5.3 @@ -69,9 +98,10 @@ public interface Cache extends jakarta.persistence.Cache { void evictEntityData(Class entityClass, Object identifier); /** - * Evicts the entity data for a particular entity "instance". + * Evict the cached item for the entity of the type with the given name, + * and with the given identifier, if there is any such item in the cache. * - * @param entityName The entity name. + * @param entityName The entity name * @param identifier The entity identifier * * @since 5.3 @@ -79,27 +109,32 @@ public interface Cache extends jakarta.persistence.Cache { void evictEntityData(String entityName, Object identifier); /** - * Evicts all entity data from the given region (i.e. for all entities of - * type). + * Evict all cached data from the cache region to which the given entity + * type is assigned. Thus, every cached item for the given entity type will + * be evicted, along with any cached items for any other entity type + * assigned to the same cache region. * - * @param entityClass The entity class. + * @param entityClass The entity type * * @since 5.3 */ void evictEntityData(Class entityClass); /** - * Evicts all entity data from the given region (i.e. for all entities of - * type). + * Evict all cached data from the cache region to which the given named + * entity type is assigned. Thus, every cached item for the given entity + * type will be evicted, along with any cached items for any other entity + * type assigned to the same cache region. * - * @param entityName The entity name. + * @param entityName The entity name * * @since 5.3 */ void evictEntityData(String entityName); /** - * Evict data from all entity regions. + * Evict all cached data from every cache region to which any entity type + * is assigned. * * @since 5.3 */ @@ -111,25 +146,26 @@ public interface Cache extends jakarta.persistence.Cache { /** - * Evict cached data for the given entity's natural-id + * Evict all cached natural id mappings for the given entity type. * - * @param entityClass The entity class. + * @param entityClass The entity type * * @since 5.3 */ void evictNaturalIdData(Class entityClass); /** - * Evict cached data for the given entity's natural-id + * Evict all cached natural id mappings for the entity type with the + * given name. * - * @param entityName The entity name. + * @param entityName The entity name * * @since 5.3 */ void evictNaturalIdData(String entityName); /** - * Evict cached data for all natural-ids (for all entities) + * Evict all cached natural id mappings for every entity type. * * @since 5.3 */ @@ -142,25 +178,23 @@ public interface Cache extends jakarta.persistence.Cache { // Collection data /** - * Determine whether the cache contains data for the given collection. - *

- * The semantic here is whether the cache contains data visible for the - * current call context. + * Determine whether the cache contains an item for the collection with the + * given role and given identifier. * - * @param role The name of the collection role (in form - * [owner-entity-name].[collection-property-name]) whose regions should be - * evicted. + * @param role The name of the collection role in the form + * {@code package.OwnerEntityName.collectionPropertyName} * @param ownerIdentifier The identifier of the owning entity * * @return True if the underlying cache contains corresponding data; false otherwise. */ boolean containsCollection(String role, Object ownerIdentifier); - /** - * Evicts the cache data for the given identified collection "instance" + * Evict the cached item for the collection with the given role and given + * identifier, if there is any such item in the cache. * - * @param role The "collection role" (in form [owner-entity-name].[collection-property-name]). + * @param role The name of the collection role in the form + * {@code package.OwnerEntityName.collectionPropertyName} * @param ownerIdentifier The identifier of the owning entity * * @since 5.3 @@ -168,16 +202,19 @@ public interface Cache extends jakarta.persistence.Cache { void evictCollectionData(String role, Object ownerIdentifier); /** - * Evicts cached data for the given collection role + * Evict all cached data from the cache region to which the given collection + * role is assigned. * - * @param role The "collection role" (in form [owner-entity-name].[collection-property-name]). + * @param role The name of the collection role in the form + * {@code package.OwnerEntityName.collectionPropertyName} * * @since 5.3 */ void evictCollectionData(String role); /** - * Evict cache data for all collections + * Evict all cache data from every cache region to which some collection + * role is assigned. * * @since 5.3 */ @@ -190,31 +227,28 @@ public interface Cache extends jakarta.persistence.Cache { // Query result data /** - * Determine whether the cache contains data for the given query. - *

- * The semantic here is whether the cache contains any data for the given - * region name since query result caches are not transactionally isolated. + * Determine whether the given region name contains cached query results. * - * @param regionName The cache name given to the query. + * @param regionName The name of a cache region to which some query is assigned * * @return True if the underlying cache contains corresponding data; false otherwise. */ boolean containsQuery(String regionName); /** - * Evicts all cached query results from the default region. + * Evict all cached query results from the default region. */ void evictDefaultQueryRegion(); /** - * Evicts all cached query results under the given name. + * Evict all cached query results from the region with the given name. * * @param regionName The cache name associated to the queries being cached. */ void evictQueryRegion(String regionName); /** - * Evict data from all query regions. + * Evict all cached query results from every region. */ void evictQueryRegions(); @@ -224,7 +258,7 @@ public interface Cache extends jakarta.persistence.Cache { // Misc /** - * Evict all data from the named cache region + * Evict all cached data from the named cache region. * * @since 5.3 */ @@ -233,10 +267,11 @@ public interface Cache extends jakarta.persistence.Cache { /** * {@inheritDoc} * - * @apiNote Hibernate impl - we only evict entity data here in keeping - * with the JPA intent (JPA only defines caching for entity data). For - * evicting all cache regions (collections, natural-ids and query results), - * use {@link #evictAllRegions} instead. + * @apiNote This operation only affects cached data for entities, in keeping + * with the intent of the JPA specification, which only defines caching for + * entity data. To evict all data from every cache region, including cached + * collections, natural-id mappings, and cached query results, use + * {@link #evictAllRegions()} instead. */ @Override default void evictAll() { @@ -245,7 +280,7 @@ public interface Cache extends jakarta.persistence.Cache { } /** - * Evict data from all cache regions. + * Evict all cached data from every cache region. */ default void evictAllRegions() { evictEntityData(); @@ -361,7 +396,7 @@ public interface Cache extends jakarta.persistence.Cache { /** * Evicts the cache data for the given identified collection instance. * - * @param role The "collection role" (in form [owner-entity-name].[collection-property-name]). + * @param role The "collection role" (of form {@code package.OwnerEntityName.collectionPropertyName}). * @param ownerIdentifier The identifier of the owning entity * * @deprecated Use {@link Cache#evictCollectionData(String, Object)} instead @@ -372,8 +407,8 @@ public interface Cache extends jakarta.persistence.Cache { } /** - * Evicts all entity data from the given region (i.e. evicts cached data - * for all of the specified collection role). + * Evicts all entity data from the given region (i.e. evicts all cached data + * for the specified collection role). * * @param role The "collection role" (in form [owner-entity-name].[collection-property-name]). * diff --git a/hibernate-core/src/main/java/org/hibernate/cache/internal/DisabledCaching.java b/hibernate-core/src/main/java/org/hibernate/cache/internal/DisabledCaching.java index ef9fc99f92..8db2ea7f5b 100644 --- a/hibernate-core/src/main/java/org/hibernate/cache/internal/DisabledCaching.java +++ b/hibernate-core/src/main/java/org/hibernate/cache/internal/DisabledCaching.java @@ -23,7 +23,7 @@ import org.hibernate.internal.util.collections.ArrayHelper; import org.hibernate.metamodel.model.domain.NavigableRole; /** - * CacheImplementor implementation for disabled caching + * A {@link CacheImplementor} service used when the second-level cache is disabled. * * @author Steve Ebersole */ @@ -52,7 +52,7 @@ public class DisabledCaching implements CacheImplementor { } @Override - public boolean containsEntity(Class entityClass, Object identifier) { + public boolean containsEntity(Class entityClass, Object identifier) { return false; } @@ -62,7 +62,7 @@ public class DisabledCaching implements CacheImplementor { } @Override - public void evictEntityData(Class entityClass, Object identifier) { + public void evictEntityData(Class entityClass, Object identifier) { // nothing to do } @@ -74,7 +74,7 @@ public class DisabledCaching implements CacheImplementor { } @Override - public void evictEntityData(Class entityClass) { + public void evictEntityData(Class entityClass) { // nothing to do } @@ -89,7 +89,7 @@ public class DisabledCaching implements CacheImplementor { } @Override - public void evictNaturalIdData(Class entityClass) { + public void evictNaturalIdData(Class entityClass) { // nothing to do } @@ -177,7 +177,7 @@ public class DisabledCaching implements CacheImplementor { public void close() { } - @Override + @Override @Deprecated public String[] getSecondLevelCacheRegionNames() { return ArrayHelper.EMPTY_STRING_ARRAY; } @@ -187,17 +187,17 @@ public class DisabledCaching implements CacheImplementor { return null; } - @Override + @Override @Deprecated public EntityDataAccess getEntityRegionAccess(NavigableRole rootEntityName) { return null; } - @Override + @Override @Deprecated public NaturalIdDataAccess getNaturalIdCacheRegionAccessStrategy(NavigableRole rootEntityName) { return null; } - @Override + @Override @Deprecated public CollectionDataAccess getCollectionRegionAccess(NavigableRole collectionRole) { return null; } diff --git a/hibernate-core/src/main/java/org/hibernate/cache/internal/EnabledCaching.java b/hibernate-core/src/main/java/org/hibernate/cache/internal/EnabledCaching.java index f491d87bf6..14107e9074 100644 --- a/hibernate-core/src/main/java/org/hibernate/cache/internal/EnabledCaching.java +++ b/hibernate-core/src/main/java/org/hibernate/cache/internal/EnabledCaching.java @@ -45,6 +45,8 @@ import org.hibernate.persister.entity.EntityPersister; import org.hibernate.pretty.MessageHelper; /** + * A {@link CacheImplementor} service used when the second-level cache is enabled. + * * @author Steve Ebersole * @author Strong Liu * @author Gail Badner @@ -129,7 +131,7 @@ public class EnabledCaching implements CacheImplementor, DomainDataRegionBuildin // Entity caching for ( EntityDataCachingConfig entityAccessConfig : regionConfig.getEntityCaching() ) { - final EntityDataAccess entityDataAccess = entityAccessMap.put( + entityAccessMap.put( entityAccessConfig.getNavigableRole(), region.getEntityDataAccess( entityAccessConfig.getNavigableRole() ) ); @@ -168,7 +170,7 @@ public class EnabledCaching implements CacheImplementor, DomainDataRegionBuildin // Collection caching for ( CollectionDataCachingConfig collectionAccessConfig : regionConfig.getCollectionCaching() ) { - final CollectionDataAccess collectionDataAccess = collectionAccessMap.put( + collectionAccessMap.put( collectionAccessConfig.getNavigableRole(), region.getCollectionDataAccess( collectionAccessConfig.getNavigableRole() ) ); @@ -219,7 +221,7 @@ public class EnabledCaching implements CacheImplementor, DomainDataRegionBuildin // Entity data @Override - public boolean containsEntity(Class entityClass, Object identifier) { + public boolean containsEntity(Class entityClass, Object identifier) { return containsEntity( entityClass.getName(), identifier ); } @@ -236,7 +238,7 @@ public class EnabledCaching implements CacheImplementor, DomainDataRegionBuildin } @Override - public void evictEntityData(Class entityClass, Object identifier) { + public void evictEntityData(Class entityClass, Object identifier) { evictEntityData( entityClass.getName(), identifier ); } @@ -260,7 +262,7 @@ public class EnabledCaching implements CacheImplementor, DomainDataRegionBuildin } @Override - public void evictEntityData(Class entityClass) { + public void evictEntityData(Class entityClass) { evictEntityData( entityClass.getName() ); } @@ -305,7 +307,7 @@ public class EnabledCaching implements CacheImplementor, DomainDataRegionBuildin // Natural-id data @Override - public void evictNaturalIdData(Class entityClass) { + public void evictNaturalIdData(Class entityClass) { evictNaturalIdData( entityClass.getName() ); } @@ -499,7 +501,7 @@ public class EnabledCaching implements CacheImplementor, DomainDataRegionBuildin this::makeQueryResultsRegion ); final QueryResultsRegion queryResultsRegion; - if ( QueryResultsRegion.class.isInstance( region ) ) { + if ( region instanceof QueryResultsRegion ) { queryResultsRegion = (QueryResultsRegion) region; } else { @@ -589,22 +591,22 @@ public class EnabledCaching implements CacheImplementor, DomainDataRegionBuildin // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Deprecations - @Override + @Override @Deprecated public EntityDataAccess getEntityRegionAccess(NavigableRole rootEntityName) { return entityAccessMap.get( rootEntityName ); } - @Override + @Override @Deprecated public NaturalIdDataAccess getNaturalIdCacheRegionAccessStrategy(NavigableRole rootEntityName) { return naturalIdAccessMap.get( rootEntityName ); } - @Override + @Override @Deprecated public CollectionDataAccess getCollectionRegionAccess(NavigableRole collectionRole) { return collectionAccessMap.get( collectionRole ); } - @Override + @Override @Deprecated public String[] getSecondLevelCacheRegionNames() { return ArrayHelper.toStringArray( legacySecondLevelCacheNames ); } diff --git a/hibernate-core/src/main/java/org/hibernate/cache/spi/CacheImplementor.java b/hibernate-core/src/main/java/org/hibernate/cache/spi/CacheImplementor.java index c60d3d0f4d..ea36e38f61 100644 --- a/hibernate-core/src/main/java/org/hibernate/cache/spi/CacheImplementor.java +++ b/hibernate-core/src/main/java/org/hibernate/cache/spi/CacheImplementor.java @@ -22,14 +22,15 @@ import org.hibernate.persister.entity.EntityPersister; import org.hibernate.service.Service; /** - * SPI contract for Hibernate's second-level cache engine + * An SPI supported by any Hibernate {@linkplain Service service} that provides an + * implementation of the {@link Cache} API. Extends {@code Cache} with operations + * called internally by Hibernate. * * @since 4.1 * * @author Strong Liu * @author Steve Ebersole */ -@SuppressWarnings("unused") public interface CacheImplementor extends Service, Cache, Serializable { @Override SessionFactoryImplementor getSessionFactory(); @@ -107,7 +108,10 @@ public interface CacheImplementor extends Service, Cache, Serializable { /** * Clean up the default query cache + * + * @deprecated only because it's currently never called */ + @Deprecated default void evictQueries() throws HibernateException { QueryResultsCache cache = getDefaultQueryResultsCache(); if ( cache != null ) { @@ -158,7 +162,7 @@ public interface CacheImplementor extends Service, Cache, Serializable { * @apiNote It is only valid to call this method after {@link #prime} has * been performed * - * @deprecated Use {@link EntityPersister#getNaturalIdCacheAccessStrategy()} ()} instead + * @deprecated Use {@link EntityPersister#getNaturalIdCacheAccessStrategy()} instead */ @Deprecated NaturalIdDataAccess getNaturalIdCacheRegionAccessStrategy(NavigableRole rootEntityName); @@ -170,7 +174,7 @@ public interface CacheImplementor extends Service, Cache, Serializable { * @apiNote It is only valid to call this method after {@link #prime} has * been performed * - * @deprecated Use {@link EntityPersister#getNaturalIdCacheAccessStrategy()} ()} instead + * @deprecated Use {@link EntityPersister#getNaturalIdCacheAccessStrategy()} instead */ @Deprecated CollectionDataAccess getCollectionRegionAccess(NavigableRole collectionRole); diff --git a/hibernate-core/src/main/java/org/hibernate/cache/spi/DirectAccessRegion.java b/hibernate-core/src/main/java/org/hibernate/cache/spi/DirectAccessRegion.java index 53bd3725d7..559c07018d 100644 --- a/hibernate-core/src/main/java/org/hibernate/cache/spi/DirectAccessRegion.java +++ b/hibernate-core/src/main/java/org/hibernate/cache/spi/DirectAccessRegion.java @@ -9,11 +9,10 @@ package org.hibernate.cache.spi; import org.hibernate.engine.spi.SharedSessionContractImplementor; /** - * Specialized Region whose data is accessed directly (not requiring - * key/item wrapping, e.g. + * Specialized Region whose data is accessed directly (not requiring key/item wrapping). * - * Does not define a "remove" operation because Hibernate's query and timestamps - * caches only ever "get" and "put" + * Does not define a "remove" operation because Hibernate's query and timestamps caches + * only ever "get" and "put" * * @author Steve Ebersole */ diff --git a/hibernate-core/src/main/java/org/hibernate/cache/spi/access/CachedDomainDataAccess.java b/hibernate-core/src/main/java/org/hibernate/cache/spi/access/CachedDomainDataAccess.java index c161e6d9f3..46e18d415b 100644 --- a/hibernate-core/src/main/java/org/hibernate/cache/spi/access/CachedDomainDataAccess.java +++ b/hibernate-core/src/main/java/org/hibernate/cache/spi/access/CachedDomainDataAccess.java @@ -6,7 +6,6 @@ */ package org.hibernate.cache.spi.access; -import java.io.Serializable; import jakarta.persistence.Cache; import org.hibernate.cache.CacheException; @@ -143,7 +142,6 @@ public interface CachedDomainDataAccess { * Remove all data for this accessed type * * @throws CacheException Propagated from underlying cache provider - * @param session */ void removeAll(SharedSessionContractImplementor session); @@ -191,8 +189,8 @@ public interface CachedDomainDataAccess { * it is also required by JPA - so we cannot remove it. *

* Used from JPA's {@link jakarta.persistence.Cache#evict(Class, Object)}, as well as the - * Hibernate extension {@link org.hibernate.Cache#evictEntityData(Class, Serializable)} - * and {@link org.hibernate.Cache#evictEntityData(String, Serializable)} + * Hibernate extension {@link org.hibernate.Cache#evictEntityData(Class, Object)} + * and {@link org.hibernate.Cache#evictEntityData(String, Object)} * * @param key The key of the item to remove * diff --git a/hibernate-core/src/main/java/org/hibernate/stat/internal/StatisticsImpl.java b/hibernate-core/src/main/java/org/hibernate/stat/internal/StatisticsImpl.java index b4f7df0170..cff35078a6 100644 --- a/hibernate-core/src/main/java/org/hibernate/stat/internal/StatisticsImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/stat/internal/StatisticsImpl.java @@ -423,7 +423,7 @@ public class StatisticsImpl implements StatisticsImplementor, Service { ); } - @Override + @Override @Deprecated public DeprecatedNaturalIdCacheStatisticsImpl getNaturalIdCacheStatistics(String regionName) { final String key = cache.unqualifyRegionName( regionName ); return deprecatedNaturalIdStatsMap.getOrCompute( @@ -548,7 +548,7 @@ public class StatisticsImpl implements StatisticsImplementor, Service { // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Second-level cache region stats - @Override + @Override @Deprecated public String[] getSecondLevelCacheRegionNames() { return cache.getSecondLevelCacheRegionNames(); } @@ -977,6 +977,7 @@ public class StatisticsImpl implements StatisticsImplementor, Service { return new NaturalIdStatisticsImpl( entityDescriptor ); } + @Deprecated private DeprecatedNaturalIdCacheStatisticsImpl instantiateDeprecatedNaturalIdCacheStatistics(final String unqualifiedRegionName) { return new DeprecatedNaturalIdCacheStatisticsImpl( unqualifiedRegionName,