From c773d352b7c7825e4ccca127f2a1aafc7ef1ba9e Mon Sep 17 00:00:00 2001 From: Gavin King Date: Fri, 29 Aug 2025 16:48:31 +1000 Subject: [PATCH] cleanups to org.hibernate.cache and subpackages --- .../src/main/java/org/hibernate/Cache.java | 20 +- .../hibernate/ConnectionAcquisitionMode.java | 4 +- .../main/java/org/hibernate/Hibernate.java | 18 +- .../CollectionDataCachingConfigImpl.java | 9 +- .../internal/DomainDataRegionConfigImpl.java | 37 ++-- .../internal/EntityDataCachingConfigImpl.java | 6 +- .../NaturalIdDataCachingConfigImpl.java | 4 +- .../cfg/spi/CollectionDataCachingConfig.java | 2 +- .../cfg/spi/EntityDataCachingConfig.java | 2 +- .../internal/CacheKeyImplementation.java | 3 +- .../internal/CollectionCacheInvalidator.java | 35 ++-- .../cache/internal/DisabledCaching.java | 27 ++- .../cache/internal/EnabledCaching.java | 187 +++++++++--------- .../cache/internal/NaturalIdCacheKey.java | 21 +- ...CachingTransactionSynchronizationImpl.java | 8 +- .../cache/internal/QueryResultsCacheImpl.java | 64 +++--- .../internal/RegionFactoryInitiator.java | 35 ++-- .../StrategyCreatorRegionFactoryImpl.java | 8 +- .../internal/TimestampsCacheDisabledImpl.java | 12 +- .../internal/TimestampsCacheEnabledImpl.java | 40 ++-- .../org/hibernate/cache/spi/QueryKey.java | 55 ++---- .../cache/spi/entry/StructuredCacheEntry.java | 2 +- .../entry/StructuredCollectionCacheEntry.java | 6 +- .../spi/entry/StructuredMapCacheEntry.java | 15 +- .../spi/support/AbstractDomainDataRegion.java | 89 ++++----- .../spi/support/AbstractReadWriteAccess.java | 80 +++++--- .../cache/spi/support/CacheUtils.java | 22 --- .../support/CollectionReadWriteAccess.java | 7 +- .../spi/support/DomainDataRegionTemplate.java | 14 +- .../EntityNonStrictReadWriteAccess.java | 5 - .../spi/support/EntityReadWriteAccess.java | 35 ++-- .../NaturalIdNonStrictReadWriteAccess.java | 10 - .../spi/support/NaturalIdReadWriteAccess.java | 29 ++- .../spi/support/RegionNameQualifier.java | 13 +- .../cache/spi/support/SimpleTimestamper.java | 1 - .../test/service/ServiceContributorTest.java | 18 +- 36 files changed, 424 insertions(+), 519 deletions(-) delete mode 100644 hibernate-core/src/main/java/org/hibernate/cache/spi/support/CacheUtils.java diff --git a/hibernate-core/src/main/java/org/hibernate/Cache.java b/hibernate-core/src/main/java/org/hibernate/Cache.java index b257917c44ea..3652a297f956 100644 --- a/hibernate-core/src/main/java/org/hibernate/Cache.java +++ b/hibernate-core/src/main/java/org/hibernate/Cache.java @@ -329,28 +329,20 @@ public interface Cache extends jakarta.persistence.Cache { void evictRegion(String regionName); /** - * {@inheritDoc} + * Evict all cached entity data. * * @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 + * collections, natural id mappings, and cached query results, use * {@link #evictAllRegions()} instead. */ @Override - default void evictAll() { - // Evict only the "JPA cache", which is purely defined as the entity regions. - evictEntityData(); - } + void evictAll(); /** - * Evict all cached data from every cache region. + * Evict all cached data from every cache region, including cached + * collections, natural id mappings, and cached query results. */ - default void evictAllRegions() { - evictEntityData(); - evictNaturalIdData(); - evictCollectionData(); - evictDefaultQueryRegion(); - evictQueryRegions(); - } + void evictAllRegions(); } diff --git a/hibernate-core/src/main/java/org/hibernate/ConnectionAcquisitionMode.java b/hibernate-core/src/main/java/org/hibernate/ConnectionAcquisitionMode.java index c11a368479d2..8d3a2330c668 100644 --- a/hibernate-core/src/main/java/org/hibernate/ConnectionAcquisitionMode.java +++ b/hibernate-core/src/main/java/org/hibernate/ConnectionAcquisitionMode.java @@ -31,7 +31,8 @@ public enum ConnectionAcquisitionMode { AS_NEEDED; public static ConnectionAcquisitionMode interpret(String value) { - return "immediate".equalsIgnoreCase( value ) || "immediately".equalsIgnoreCase( value ) + return "immediate".equalsIgnoreCase( value ) + || "immediately".equalsIgnoreCase( value ) ? IMMEDIATELY : AS_NEEDED; } @@ -47,6 +48,5 @@ else if ( setting instanceof ConnectionAcquisitionMode mode ) { final String value = setting.toString(); return isEmpty( value ) ? null : interpret( value ); } - } } diff --git a/hibernate-core/src/main/java/org/hibernate/Hibernate.java b/hibernate-core/src/main/java/org/hibernate/Hibernate.java index 4b3a24feb38e..183ae3054cdb 100644 --- a/hibernate-core/src/main/java/org/hibernate/Hibernate.java +++ b/hibernate-core/src/main/java/org/hibernate/Hibernate.java @@ -36,9 +36,7 @@ import org.hibernate.engine.jdbc.env.internal.NonContextualLobCreator; import org.hibernate.engine.spi.PersistentAttributeInterceptor; import org.hibernate.engine.spi.SessionFactoryImplementor; -import org.hibernate.persister.entity.EntityPersister; import org.hibernate.proxy.HibernateProxy; -import org.hibernate.proxy.LazyInitializer; import org.hibernate.collection.spi.LazyInitializable; import static org.hibernate.engine.internal.ManagedTypeHelper.asPersistentAttributeInterceptable; @@ -132,7 +130,7 @@ private Hibernate() { */ public static void initialize(Object proxy) throws HibernateException { if ( proxy != null ) { - final LazyInitializer lazyInitializer = extractLazyInitializer( proxy ); + final var lazyInitializer = extractLazyInitializer( proxy ); if ( lazyInitializer != null ) { lazyInitializer.initialize(); } @@ -157,7 +155,7 @@ else if ( isPersistentAttributeInterceptable( proxy ) ) { * @return true if the argument is already initialized, or is not a proxy or collection */ public static boolean isInitialized(Object proxy) { - final LazyInitializer lazyInitializer = extractLazyInitializer( proxy ); + final var lazyInitializer = extractLazyInitializer( proxy ); if ( lazyInitializer != null ) { return !lazyInitializer.isUninitialized(); } @@ -264,7 +262,7 @@ public static T get(List list, int key) { */ @SuppressWarnings("unchecked") public static Class getClass(T proxy) { - final LazyInitializer lazyInitializer = extractLazyInitializer( proxy ); + final var lazyInitializer = extractLazyInitializer( proxy ); final Class result = lazyInitializer != null ? lazyInitializer.getImplementation().getClass() @@ -287,7 +285,7 @@ public static Class getClass(T proxy) { */ @SuppressWarnings("unchecked") public static Class getClassLazy(T proxy) { - final LazyInitializer lazyInitializer = extractLazyInitializer( proxy ); + final var lazyInitializer = extractLazyInitializer( proxy ); final Class result = lazyInitializer != null ? lazyInitializer.getImplementationClass() @@ -339,7 +337,7 @@ public static boolean isPropertyInitialized(E entity, Attribute void initializeProperty(E entity, Attribute attr * @see jakarta.persistence.PersistenceUnitUtil#load(Object, String) */ public static void initializeProperty(Object proxy, String attributeName) { - final LazyInitializer lazyInitializer = extractLazyInitializer( proxy ); + final var lazyInitializer = extractLazyInitializer( proxy ); final Object entity = lazyInitializer != null ? lazyInitializer.getImplementation() : proxy; if ( isPersistentAttributeInterceptable( entity ) ) { getAttributeInterceptor( entity ).readObject( entity, attributeName, null ); @@ -401,7 +399,7 @@ public static void initializeProperty(Object proxy, String attributeName) { * uninitialized proxy that is not associated with an open session. */ public static Object unproxy(Object proxy) { - final LazyInitializer lazyInitializer = extractLazyInitializer( proxy ); + final var lazyInitializer = extractLazyInitializer( proxy ); return lazyInitializer != null ? lazyInitializer.getImplementation() : proxy; } @@ -439,7 +437,7 @@ public static T unproxy(T proxy, Class entityClass) { */ @SuppressWarnings("unchecked") public static E createDetachedProxy(SessionFactory sessionFactory, Class entityClass, Object id) { - final EntityPersister persister = + final var persister = sessionFactory.unwrap( SessionFactoryImplementor.class ) .getMappingMetamodel() .findEntityDescriptor( entityClass ); diff --git a/hibernate-core/src/main/java/org/hibernate/cache/cfg/internal/CollectionDataCachingConfigImpl.java b/hibernate-core/src/main/java/org/hibernate/cache/cfg/internal/CollectionDataCachingConfigImpl.java index a38677fe6f9b..c86988aaab33 100644 --- a/hibernate-core/src/main/java/org/hibernate/cache/cfg/internal/CollectionDataCachingConfigImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/cache/cfg/internal/CollectionDataCachingConfigImpl.java @@ -40,11 +40,14 @@ public boolean isVersioned() { } @Override - public Comparator getOwnerVersionComparator() { - if ( !isVersioned() ) { + public Comparator getOwnerVersionComparator() { + if ( isVersioned() ) { + final var type = (BasicType) collectionDescriptor.getOwner().getVersion().getType(); + return type.getJavaTypeDescriptor().getComparator(); + } + else { return null; } - return ( (BasicType) collectionDescriptor.getOwner().getVersion().getType() ).getJavaTypeDescriptor().getComparator(); } @Override diff --git a/hibernate-core/src/main/java/org/hibernate/cache/cfg/internal/DomainDataRegionConfigImpl.java b/hibernate-core/src/main/java/org/hibernate/cache/cfg/internal/DomainDataRegionConfigImpl.java index 40ac5a88a6a9..46319bac9841 100644 --- a/hibernate-core/src/main/java/org/hibernate/cache/cfg/internal/DomainDataRegionConfigImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/cache/cfg/internal/DomainDataRegionConfigImpl.java @@ -5,7 +5,6 @@ package org.hibernate.cache.cfg.internal; import java.util.ArrayList; -import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -22,6 +21,9 @@ import org.hibernate.metamodel.model.domain.NavigableRole; import org.hibernate.type.BasicType; +import static java.util.Collections.emptyList; +import static java.util.Collections.unmodifiableList; + /** * DomainDataRegionConfig implementation * @@ -89,25 +91,27 @@ public Builder addEntityConfig(PersistentClass bootEntityDescriptor, AccessType // todo (5.3) : this is another place where having `BootstrapContext` / `TypeConfiguration` helps // would allow us to delay the attempt to resolve the comparator (usual timing issues wrt Type resolution) - final NavigableRole rootEntityName = new NavigableRole( bootEntityDescriptor.getRootClass().getEntityName() ); - final EntityDataCachingConfigImpl entityDataCachingConfig = entityConfigsByRootName.computeIfAbsent( + final var rootEntityName = new NavigableRole( bootEntityDescriptor.getRootClass().getEntityName() ); + final var entityDataCachingConfig = entityConfigsByRootName.computeIfAbsent( rootEntityName, x -> new EntityDataCachingConfigImpl( rootEntityName, bootEntityDescriptor.isVersioned() - ? () -> ( (BasicType) bootEntityDescriptor.getVersion().getType() ).getJavaTypeDescriptor().getComparator() + ? () -> { + final var type = (BasicType) bootEntityDescriptor.getVersion().getType(); + return type.getJavaTypeDescriptor().getComparator(); + } : null, bootEntityDescriptor.isMutable(), accessType ) ); - if ( bootEntityDescriptor == bootEntityDescriptor.getRootClass() ) { - entityDataCachingConfig.addCachedType( rootEntityName ); - } - else { - entityDataCachingConfig.addCachedType( new NavigableRole( bootEntityDescriptor.getEntityName() ) ); - } + final var cachedRole = + bootEntityDescriptor == bootEntityDescriptor.getRootClass() + ? rootEntityName + : new NavigableRole( bootEntityDescriptor.getEntityName() ); + entityDataCachingConfig.addCachedType( cachedRole ); return this; } @@ -123,7 +127,6 @@ public Builder addNaturalIdConfig(RootClass rootEntityDescriptor, AccessType acc if ( naturalIdConfigs == null ) { naturalIdConfigs = new ArrayList<>(); } - naturalIdConfigs.add( new NaturalIdDataCachingConfigImpl( rootEntityDescriptor, accessType ) ); return this; } @@ -133,7 +136,6 @@ public Builder addCollectionConfig(Collection collectionDescriptor, AccessType a if ( collectionConfigs == null ) { collectionConfigs = new ArrayList<>(); } - collectionConfigs.add( new CollectionDataCachingConfigImpl( collectionDescriptor, accessType ) ); return this; } @@ -147,17 +149,16 @@ public DomainDataRegionConfigImpl build() { ); } - @SuppressWarnings("unchecked") - private List finalize(Map configs) { + private List finalize(Map configs) { return configs == null - ? Collections.emptyList() - : Collections.unmodifiableList( new ArrayList( configs.values() ) ); + ? emptyList() + : unmodifiableList( new ArrayList<>( configs.values() ) ); } private List finalize(List configs) { return configs == null - ? Collections.emptyList() - : Collections.unmodifiableList( configs ); + ? emptyList() + : unmodifiableList( configs ); } } diff --git a/hibernate-core/src/main/java/org/hibernate/cache/cfg/internal/EntityDataCachingConfigImpl.java b/hibernate-core/src/main/java/org/hibernate/cache/cfg/internal/EntityDataCachingConfigImpl.java index d5b3befd7d59..456bbffd91e3 100644 --- a/hibernate-core/src/main/java/org/hibernate/cache/cfg/internal/EntityDataCachingConfigImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/cache/cfg/internal/EntityDataCachingConfigImpl.java @@ -20,14 +20,14 @@ public class EntityDataCachingConfigImpl extends AbstractDomainDataCachingConfig implements EntityDataCachingConfig { private final NavigableRole navigableRole; - private final Supplier versionComparatorAccess; + private final Supplier> versionComparatorAccess; private final boolean isEntityMutable; private final Set cachedTypes = new HashSet<>(); public EntityDataCachingConfigImpl( NavigableRole rootEntityName, - Supplier versionComparatorAccess, + Supplier> versionComparatorAccess, boolean isEntityMutable, AccessType accessType) { super( accessType ); @@ -37,7 +37,7 @@ public EntityDataCachingConfigImpl( } @Override - public Supplier getVersionComparatorAccess() { + public Supplier> getVersionComparatorAccess() { return versionComparatorAccess; } diff --git a/hibernate-core/src/main/java/org/hibernate/cache/cfg/internal/NaturalIdDataCachingConfigImpl.java b/hibernate-core/src/main/java/org/hibernate/cache/cfg/internal/NaturalIdDataCachingConfigImpl.java index 6e28d79a2553..1f8d7e258d95 100644 --- a/hibernate-core/src/main/java/org/hibernate/cache/cfg/internal/NaturalIdDataCachingConfigImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/cache/cfg/internal/NaturalIdDataCachingConfigImpl.java @@ -26,8 +26,7 @@ public NaturalIdDataCachingConfigImpl( super( accessType ); this.rootEntityDescriptor = rootEntityDescriptor; this.navigableRole = new NavigableRole( rootEntityDescriptor.getEntityName() ); - - // sucks that we need to do this here. persister does the same "calculation" + // Sucks that we need to do this here. Persister does the same "calculation" this.mutable = hasAnyMutableNaturalIdProps(); } @@ -37,7 +36,6 @@ private boolean hasAnyMutableNaturalIdProps() { return true; } } - return false; } diff --git a/hibernate-core/src/main/java/org/hibernate/cache/cfg/spi/CollectionDataCachingConfig.java b/hibernate-core/src/main/java/org/hibernate/cache/cfg/spi/CollectionDataCachingConfig.java index 4751fa695569..53a2067c4a8f 100644 --- a/hibernate-core/src/main/java/org/hibernate/cache/cfg/spi/CollectionDataCachingConfig.java +++ b/hibernate-core/src/main/java/org/hibernate/cache/cfg/spi/CollectionDataCachingConfig.java @@ -16,5 +16,5 @@ public interface CollectionDataCachingConfig extends DomainDataCachingConfig { /** * The comparator to be used with the owning entity's version (if it has one). */ - Comparator getOwnerVersionComparator(); + Comparator getOwnerVersionComparator(); } diff --git a/hibernate-core/src/main/java/org/hibernate/cache/cfg/spi/EntityDataCachingConfig.java b/hibernate-core/src/main/java/org/hibernate/cache/cfg/spi/EntityDataCachingConfig.java index 533bda1fc7a8..1ad5569bc660 100644 --- a/hibernate-core/src/main/java/org/hibernate/cache/cfg/spi/EntityDataCachingConfig.java +++ b/hibernate-core/src/main/java/org/hibernate/cache/cfg/spi/EntityDataCachingConfig.java @@ -32,7 +32,7 @@ public interface EntityDataCachingConfig extends DomainDataCachingConfig { * version. If the entity is not versioned, then this method * returns {@code null}. */ - Supplier getVersionComparatorAccess(); + Supplier> getVersionComparatorAccess(); /** * The list of specific subclasses of the root that are actually diff --git a/hibernate-core/src/main/java/org/hibernate/cache/internal/CacheKeyImplementation.java b/hibernate-core/src/main/java/org/hibernate/cache/internal/CacheKeyImplementation.java index a7f8474720db..8b242dd4e7a9 100644 --- a/hibernate-core/src/main/java/org/hibernate/cache/internal/CacheKeyImplementation.java +++ b/hibernate-core/src/main/java/org/hibernate/cache/internal/CacheKeyImplementation.java @@ -79,8 +79,7 @@ public CacheKeyImplementation( } private static int calculateHashCode(Object id, Type type, String tenantId) { - return 31 * type.getHashCode( id ) - + ( tenantId != null ? tenantId.hashCode() : 0 ); + return 31 * type.getHashCode( id ) + Objects.hashCode( tenantId ); } public Object getId() { diff --git a/hibernate-core/src/main/java/org/hibernate/cache/internal/CollectionCacheInvalidator.java b/hibernate-core/src/main/java/org/hibernate/cache/internal/CollectionCacheInvalidator.java index 5d7fad4695e5..b08dba5fc91f 100644 --- a/hibernate-core/src/main/java/org/hibernate/cache/internal/CollectionCacheInvalidator.java +++ b/hibernate-core/src/main/java/org/hibernate/cache/internal/CollectionCacheInvalidator.java @@ -4,19 +4,14 @@ */ package org.hibernate.cache.internal; -import java.util.Set; import org.hibernate.HibernateException; import org.hibernate.action.internal.CollectionAction; import org.hibernate.boot.Metadata; import org.hibernate.boot.spi.BootstrapContext; -import org.hibernate.boot.spi.SessionFactoryOptions; -import org.hibernate.cache.spi.access.CollectionDataAccess; -import org.hibernate.cache.spi.access.SoftLock; import org.hibernate.collection.spi.PersistentCollection; import org.hibernate.engine.spi.SessionFactoryImplementor; import org.hibernate.engine.spi.SharedSessionContractImplementor; -import org.hibernate.event.service.spi.EventListenerRegistry; import org.hibernate.event.spi.EventSource; import org.hibernate.event.spi.EventType; import org.hibernate.event.spi.PostDeleteEvent; @@ -26,7 +21,6 @@ import org.hibernate.event.spi.PostUpdateEvent; import org.hibernate.event.spi.PostUpdateEventListener; import org.hibernate.integrator.spi.Integrator; -import org.hibernate.metamodel.spi.MappingMetamodelImplementor; import org.hibernate.persister.collection.CollectionPersister; import org.hibernate.persister.entity.EntityPersister; @@ -84,25 +78,20 @@ public void onPostUpdate(PostUpdateEvent event) { } private void integrate(SessionFactoryImplementor sessionFactory) { - final SessionFactoryOptions sessionFactoryOptions = sessionFactory.getSessionFactoryOptions(); - if ( !sessionFactoryOptions.isAutoEvictCollectionCache() ) { - // feature is disabled - return; + final var options = sessionFactory.getSessionFactoryOptions(); + if ( options.isSecondLevelCacheEnabled() + && options.isAutoEvictCollectionCache() ) { + final var eventListenerRegistry = sessionFactory.getEventListenerRegistry(); + eventListenerRegistry.appendListeners( EventType.POST_INSERT, this ); + eventListenerRegistry.appendListeners( EventType.POST_DELETE, this ); + eventListenerRegistry.appendListeners( EventType.POST_UPDATE, this ); } - if ( !sessionFactoryOptions.isSecondLevelCacheEnabled() ) { - // Nothing to do, if caching is disabled - return; - } - final EventListenerRegistry eventListenerRegistry = sessionFactory.getEventListenerRegistry(); - eventListenerRegistry.appendListeners( EventType.POST_INSERT, this ); - eventListenerRegistry.appendListeners( EventType.POST_DELETE, this ); - eventListenerRegistry.appendListeners( EventType.POST_UPDATE, this ); } private void evictCache(Object entity, EntityPersister persister, EventSource session, Object[] oldState) { try { - final MappingMetamodelImplementor metamodel = persister.getFactory().getMappingMetamodel(); - final Set roles = metamodel.getCollectionRolesByEntityParticipant( persister.getEntityName() ); + final var metamodel = persister.getFactory().getMappingMetamodel(); + final var roles = metamodel.getCollectionRolesByEntityParticipant( persister.getEntityName() ); if ( !isEmpty( roles ) ) { for ( String role : roles ) { evictCollection( entity, persister, oldState, metamodel.getCollectionDescriptor( role ), session ); @@ -132,8 +121,8 @@ private void evictCollection( if ( L2CACHE_LOGGER.isTraceEnabled() ) { L2CACHE_LOGGER.autoEvictingCollectionCacheByRole( collectionPersister.getRole() ); } - final CollectionDataAccess cacheAccessStrategy = collectionPersister.getCacheAccessStrategy(); - final SoftLock softLock = cacheAccessStrategy.lockRegion(); + final var cacheAccessStrategy = collectionPersister.getCacheAccessStrategy(); + final var softLock = cacheAccessStrategy.lockRegion(); session.getActionQueue() .registerProcess( (success, s) -> cacheAccessStrategy.unlockRegion( softLock ) ); } @@ -190,7 +179,7 @@ private void evict(Object id, CollectionPersister collectionPersister, EventSour L2CACHE_LOGGER.autoEvictingCollectionCache( collectionInfoString( collectionPersister, id, collectionPersister.getFactory() ) ); } - final CollectionEvictCacheAction evictCacheAction = + final var evictCacheAction = new CollectionEvictCacheAction( collectionPersister, null, id, session ); evictCacheAction.execute(); session.getActionQueue().registerProcess( evictCacheAction.getAfterTransactionCompletionProcess() ); 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 985d877b147c..8986678a4b13 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 @@ -7,6 +7,7 @@ import java.util.Collections; import java.util.Set; +import jakarta.persistence.PersistenceException; import org.hibernate.cache.cfg.spi.DomainDataRegionConfig; import org.hibernate.cache.spi.CacheImplementor; import org.hibernate.cache.spi.QueryResultsCache; @@ -61,13 +62,11 @@ public boolean containsEntity(String entityName, Object identifier) { @Override public void evictEntityData(Class entityClass, Object identifier) { // nothing to do - } @Override public void evictEntityData(String entityName, Object identifier) { // nothing to do - } @Override @@ -145,6 +144,17 @@ public void evictRegion(String regionName) { // nothing to do } + + @Override + public void evictAll() { + // nothing to do + } + + @Override + public void evictAllRegions() { + // nothing to do + } + @Override public Region getRegion(String fullRegionName) { return null; @@ -201,17 +211,22 @@ public boolean contains(Class cls, Object primaryKey) { @Override public void evict(Class cls, Object primaryKey) { - + // nothing to do } @Override public void evict(Class cls) { - + // nothing to do } @Override @SuppressWarnings("unchecked") - public T unwrap(Class cls) { - return (T) this; + public T unwrap(Class type) { + if ( type.isAssignableFrom( DisabledCaching.class ) ) { + return (T) this; + } + else { + throw new PersistenceException( "Hibernate cannot unwrap Cache as '" + type.getName() + "'" ); + } } } 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 3ad8e89b0eb4..fba56d0c3dba 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 @@ -15,12 +15,8 @@ import jakarta.persistence.PersistenceException; import org.hibernate.HibernateException; -import org.hibernate.boot.spi.SessionFactoryOptions; -import org.hibernate.cache.cfg.spi.CollectionDataCachingConfig; import org.hibernate.cache.cfg.spi.DomainDataRegionBuildingContext; import org.hibernate.cache.cfg.spi.DomainDataRegionConfig; -import org.hibernate.cache.cfg.spi.EntityDataCachingConfig; -import org.hibernate.cache.cfg.spi.NaturalIdDataCachingConfig; import org.hibernate.cache.spi.CacheImplementor; import org.hibernate.cache.spi.CacheKeysFactory; import org.hibernate.cache.spi.DomainDataRegion; @@ -29,7 +25,6 @@ import org.hibernate.cache.spi.Region; import org.hibernate.cache.spi.RegionFactory; import org.hibernate.cache.spi.TimestampsCache; -import org.hibernate.cache.spi.TimestampsRegion; import org.hibernate.cache.spi.access.CollectionDataAccess; import org.hibernate.cache.spi.access.EntityDataAccess; import org.hibernate.cache.spi.access.NaturalIdDataAccess; @@ -40,6 +35,8 @@ import org.hibernate.persister.entity.EntityPersister; import org.hibernate.cache.spi.SecondLevelCacheLogger; +import static org.hibernate.cache.spi.RegionFactory.DEFAULT_QUERY_RESULTS_REGION_UNQUALIFIED_NAME; +import static org.hibernate.cache.spi.RegionFactory.DEFAULT_UPDATE_TIMESTAMPS_REGION_UNQUALIFIED_NAME; import static org.hibernate.internal.util.StringHelper.qualifyConditionally; import static org.hibernate.pretty.MessageHelper.collectionInfoString; import static org.hibernate.pretty.MessageHelper.infoString; @@ -78,26 +75,12 @@ public class EnabledCaching implements CacheImplementor, DomainDataRegionBuildin public EnabledCaching(SessionFactoryImplementor sessionFactory) { this.sessionFactory = sessionFactory; - final SessionFactoryOptions sessionFactoryOptions = sessionFactory.getSessionFactoryOptions(); - - regionFactory = sessionFactoryOptions.getServiceRegistry().requireService( RegionFactory.class ); - regionFactory.start( sessionFactoryOptions, sessionFactory.getProperties() ); - - if ( sessionFactoryOptions.isQueryCacheEnabled() ) { - final TimestampsRegion timestampsRegion = regionFactory.buildTimestampsRegion( - RegionFactory.DEFAULT_UPDATE_TIMESTAMPS_REGION_UNQUALIFIED_NAME, - sessionFactory - ); - timestampsCache = sessionFactoryOptions.getTimestampsCacheFactory() - .buildTimestampsCache( this, timestampsRegion ); - legacySecondLevelCacheNames.add( timestampsRegion.getName() ); - - final QueryResultsRegion queryResultsRegion = regionFactory.buildQueryResultsRegion( - RegionFactory.DEFAULT_QUERY_RESULTS_REGION_UNQUALIFIED_NAME, - sessionFactory - ); - regionsByName.put( queryResultsRegion.getName(), queryResultsRegion ); - defaultQueryResultsCache = new QueryResultsCacheImpl( queryResultsRegion, timestampsCache ); + final var options = sessionFactory.getSessionFactoryOptions(); + regionFactory = options.getServiceRegistry().requireService( RegionFactory.class ); + regionFactory.start( options, sessionFactory.getProperties() ); + if ( options.isQueryCacheEnabled() ) { + timestampsCache = buildTimestampsCache( sessionFactory ); + defaultQueryResultsCache = buildQueryResultsCache( sessionFactory ); } else { timestampsCache = new TimestampsCacheDisabledImpl(); @@ -105,13 +88,33 @@ public EnabledCaching(SessionFactoryImplementor sessionFactory) { } } + private QueryResultsCache buildQueryResultsCache(SessionFactoryImplementor sessionFactory) { + final var queryResultsRegion = + regionFactory.buildQueryResultsRegion( + DEFAULT_QUERY_RESULTS_REGION_UNQUALIFIED_NAME, + sessionFactory + ); + regionsByName.put( queryResultsRegion.getName(), queryResultsRegion ); + return new QueryResultsCacheImpl( queryResultsRegion, timestampsCache ); + } + + private TimestampsCache buildTimestampsCache(SessionFactoryImplementor sessionFactory) { + final var timestampsRegion = + regionFactory.buildTimestampsRegion( + DEFAULT_UPDATE_TIMESTAMPS_REGION_UNQUALIFIED_NAME, + sessionFactory + ); + legacySecondLevelCacheNames.add( timestampsRegion.getName() ); + return sessionFactory.getSessionFactoryOptions().getTimestampsCacheFactory() + .buildTimestampsCache( this, timestampsRegion ); + } + @Override public void prime(Set cacheRegionConfigs) { - for ( DomainDataRegionConfig regionConfig : cacheRegionConfigs ) { - final DomainDataRegion region = buildRegion( regionConfig ); + for ( var regionConfig : cacheRegionConfigs ) { + final var region = buildRegion( regionConfig ); regionsByName.put( region.getName(), region ); - - if ( ! Objects.equals( region.getName(), regionConfig.getRegionName() ) ) { + if ( !Objects.equals( region.getName(), regionConfig.getRegionName() ) ) { throw new HibernateException( String.format( Locale.ROOT, @@ -127,34 +130,27 @@ public void prime(Set cacheRegionConfigs) { // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Entity caching - for ( EntityDataCachingConfig entityAccessConfig : regionConfig.getEntityCaching() ) { - entityAccessMap.put( - entityAccessConfig.getNavigableRole(), - region.getEntityDataAccess( entityAccessConfig.getNavigableRole() ) - ); - - legacySecondLevelCacheNames.add( - qualifyConditionally( - getSessionFactoryOptions().getCacheRegionPrefix(), - region.getName() - ) - ); + for ( var entityAccessConfig : regionConfig.getEntityCaching() ) { + final var navigableRole = entityAccessConfig.getNavigableRole(); + entityAccessMap.put( navigableRole, region.getEntityDataAccess( navigableRole ) ); + legacySecondLevelCacheNames.add( qualifiedRegionName( region ) ); } // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Natural-id caching - if ( regionConfig.getNaturalIdCaching().isEmpty() ) { + final var naturalIdCaching = regionConfig.getNaturalIdCaching(); + if ( naturalIdCaching.isEmpty() ) { legacyNaturalIdAccessesForRegion.put( region.getName(), Collections.emptySet() ); } else { final Set accesses = new HashSet<>(); - for ( NaturalIdDataCachingConfig naturalIdAccessConfig : regionConfig.getNaturalIdCaching() ) { - final NaturalIdDataAccess naturalIdDataAccess = naturalIdAccessMap.put( - naturalIdAccessConfig.getNavigableRole(), - region.getNaturalIdDataAccess( naturalIdAccessConfig.getNavigableRole() ) - ); + for ( var naturalIdAccessConfig : naturalIdCaching ) { + final var navigableRole = naturalIdAccessConfig.getNavigableRole(); + final var naturalIdDataAccess = + naturalIdAccessMap.put( navigableRole, + region.getNaturalIdDataAccess( navigableRole ) ); accesses.add( naturalIdDataAccess ); } legacyNaturalIdAccessesForRegion.put( region.getName(), accesses ); @@ -164,24 +160,22 @@ public void prime(Set cacheRegionConfigs) { // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Collection caching - for ( CollectionDataCachingConfig collectionAccessConfig : regionConfig.getCollectionCaching() ) { - collectionAccessMap.put( - collectionAccessConfig.getNavigableRole(), - region.getCollectionDataAccess( collectionAccessConfig.getNavigableRole() ) - ); - legacySecondLevelCacheNames.add( - qualifyConditionally( - getSessionFactoryOptions().getCacheRegionPrefix(), - region.getName() - ) - ); + for ( var collectionAccessConfig : regionConfig.getCollectionCaching() ) { + final var navigableRole = collectionAccessConfig.getNavigableRole(); + collectionAccessMap.put( navigableRole, + region.getCollectionDataAccess( navigableRole ) ); + legacySecondLevelCacheNames.add( qualifiedRegionName( region ) ); } } } - private SessionFactoryOptions getSessionFactoryOptions() { - return sessionFactory.getSessionFactoryOptions(); + private String qualifiedRegionName(DomainDataRegion region) { + return qualifyConditionally( getRegionPrefix(), region.getName() ); + } + + private String getRegionPrefix() { + return sessionFactory.getSessionFactoryOptions().getCacheRegionPrefix(); } private DomainDataRegion buildRegion(DomainDataRegionConfig regionConfig) { @@ -229,8 +223,8 @@ public boolean containsEntity(Class entityClass, Object identifier) { @Override public boolean containsEntity(String entityName, Object identifier) { - final EntityPersister persister = getEntityDescriptor( entityName ); - final EntityDataAccess cacheAccess = persister.getCacheAccessStrategy(); + final var persister = getEntityDescriptor( entityName ); + final var cacheAccess = persister.getCacheAccessStrategy(); if ( cacheAccess != null ) { final Object idValue = persister.getIdentifierMapping().getJavaType() @@ -255,11 +249,10 @@ public void evictEntityData(Class entityClass, Object identifier) { @Override public void evictEntityData(String entityName, Object identifier) { - final EntityPersister persister = getEntityDescriptor( entityName ); - final EntityDataAccess cacheAccess = persister.getCacheAccessStrategy(); + final var persister = getEntityDescriptor( entityName ); + final var cacheAccess = persister.getCacheAccessStrategy(); if ( cacheAccess != null ) { LOG.evictingEntityCache( infoString( persister, identifier, sessionFactory ) ); - final Object cacheKey = cacheAccess.generateCacheKey( identifier, persister, sessionFactory, null ); cacheAccess.evict( cacheKey ); @@ -289,16 +282,21 @@ private CollectionPersister getCollectionDescriptor(String role) { } protected void evictEntityData(EntityPersister entityDescriptor) { - EntityPersister rootEntityDescriptor = entityDescriptor; - if ( entityDescriptor.isInherited() - && ! entityDescriptor.getEntityName().equals( entityDescriptor.getRootEntityName() ) ) { - rootEntityDescriptor = entityDescriptor.getRootEntityDescriptor().getEntityPersister(); - } - + final var rootEntityDescriptor = rootEntityPersister( entityDescriptor ); evictEntityData( rootEntityDescriptor.getNavigableRole(), rootEntityDescriptor.getCacheAccessStrategy() ); } + private static EntityPersister rootEntityPersister(EntityPersister entityDescriptor) { + if ( entityDescriptor.isInherited() + && !entityDescriptor.getEntityName().equals( entityDescriptor.getRootEntityName() ) ) { + return entityDescriptor.getRootEntityDescriptor().getEntityPersister(); + } + else { + return entityDescriptor; + } + } + private void evictEntityData(NavigableRole navigableRole, EntityDataAccess cacheAccess) { if ( cacheAccess != null ) { LOG.evictingEntityCacheByRole( navigableRole.getFullPath() ); @@ -364,11 +362,10 @@ public boolean containsCollection(String role, Object ownerIdentifier) { @Override public void evictCollectionData(String role, Object ownerIdentifier) { - final CollectionPersister persister = getCollectionDescriptor( role ); - final CollectionDataAccess cacheAccess = persister.getCacheAccessStrategy(); + final var persister = getCollectionDescriptor( role ); + final var cacheAccess = persister.getCacheAccessStrategy(); if ( cacheAccess != null ) { LOG.evictingCollectionCache( collectionInfoString( persister, ownerIdentifier, sessionFactory ) ); - final Object cacheKey = cacheAccess.generateCacheKey( ownerIdentifier, persister, sessionFactory, null ); cacheAccess.evict( cacheKey ); @@ -414,7 +411,7 @@ public void evictDefaultQueryRegion() { @Override public void evictQueryRegion(String regionName) { - final QueryResultsCache cache = getQueryResultsCache( regionName ); + final var cache = getQueryResultsCache( regionName ); if ( cache != null ) { evictQueryResultRegion( cache ); } @@ -430,13 +427,27 @@ private void evictQueryResultRegion(QueryResultsCache cache) { @Override public void evictQueryRegions() { LOG.evictingAllQueryRegions(); - evictQueryResultRegion( defaultQueryResultsCache ); for ( QueryResultsCache cache : namedQueryResultsCacheMap.values() ) { evictQueryResultRegion( cache ); } } + @Override + public void evictAll() { + // Evict only the "JPA cache", which is purely defined as the entity regions. + evictEntityData(); + } + + @Override + public void evictAllRegions() { + evictEntityData(); + evictNaturalIdData(); + evictCollectionData(); + evictDefaultQueryRegion(); + evictQueryRegions(); + } + @Override public QueryResultsCache getDefaultQueryResultsCache() { return defaultQueryResultsCache; @@ -459,7 +470,7 @@ else if ( regionName == null || regionName.equals( getDefaultResultCacheName() ) return getDefaultQueryResultsCache(); } else { - final QueryResultsCache existing = namedQueryResultsCacheMap.get( regionName ); + final var existing = namedQueryResultsCacheMap.get( regionName ); return existing != null ? existing : makeQueryResultsRegionAccess( regionName ); } } @@ -478,8 +489,7 @@ else if ( regionName == null || regionName.equals( getDefaultResultCacheName() ) } protected QueryResultsCache makeQueryResultsRegionAccess(String regionName) { - final QueryResultsCacheImpl regionAccess = - new QueryResultsCacheImpl( getQueryResultsRegion( regionName ), timestampsCache ); + final var regionAccess = new QueryResultsCacheImpl( getQueryResultsRegion( regionName ), timestampsCache ); namedQueryResultsCacheMap.put( regionName, regionAccess ); legacySecondLevelCacheNames.add( regionName ); return regionAccess; @@ -504,7 +514,7 @@ public Set getCacheRegionNames() { @Override public void evictRegion(String regionName) { getRegion( regionName ).clear(); - final QueryResultsRegion queryResultsRegionWithDuplicateName = + final var queryResultsRegionWithDuplicateName = queryResultsRegionsByDuplicateName.get( regionName ); if ( queryResultsRegionWithDuplicateName != null ) { queryResultsRegionWithDuplicateName.clear(); @@ -514,26 +524,23 @@ public void evictRegion(String regionName) { @Override @SuppressWarnings("unchecked") public T unwrap(Class type) { - if ( org.hibernate.Cache.class.isAssignableFrom( type ) ) { + if ( type.isAssignableFrom( EnabledCaching.class ) ) { return (T) this; } - if ( org.hibernate.cache.spi.CacheImplementor.class.isAssignableFrom( type ) ) { - return (T) this; - } - - if ( RegionFactory.class.isAssignableFrom( type ) ) { + else if ( type.isAssignableFrom( RegionFactory.class ) ) { return (T) regionFactory; } - - throw new PersistenceException( "Hibernate cannot unwrap Cache as '" + type.getName() + "'" ); + else { + throw new PersistenceException( "Hibernate cannot unwrap Cache as '" + type.getName() + "'" ); + } } @Override public void close() { - for ( Region region : regionsByName.values() ) { + for ( var region : regionsByName.values() ) { region.destroy(); } - for ( Region region : queryResultsRegionsByDuplicateName.values() ) { + for ( var region : queryResultsRegionsByDuplicateName.values() ) { region.destroy(); } } diff --git a/hibernate-core/src/main/java/org/hibernate/cache/internal/NaturalIdCacheKey.java b/hibernate-core/src/main/java/org/hibernate/cache/internal/NaturalIdCacheKey.java index d020c6615ed8..58c90846ec48 100644 --- a/hibernate-core/src/main/java/org/hibernate/cache/internal/NaturalIdCacheKey.java +++ b/hibernate-core/src/main/java/org/hibernate/cache/internal/NaturalIdCacheKey.java @@ -40,8 +40,7 @@ public static NaturalIdCacheKey from( EntityPersister persister, String entityName, SharedSessionContractImplementor session) { - final NaturalIdCacheKeyBuilder builder = - new NaturalIdCacheKeyBuilder( entityName, session.getTenantIdentifier(), persister ); + final var builder = new NaturalIdCacheKeyBuilder( entityName, session.getTenantIdentifier(), persister ); addTenantIdToCacheKey( session, builder ); persister.getNaturalIdMapping().addToCacheKey( builder, naturalIdValues, session ); return builder.build(); @@ -82,20 +81,22 @@ public int hashCode() { } @Override - public boolean equals(Object o) { - if ( o == null ) { + public boolean equals(Object object) { + if ( object == null ) { return false; } - if ( this == o ) { + else if ( this == object ) { return true; } - if ( hashCode != o.hashCode() || !(o instanceof NaturalIdCacheKey other) ) { + else if ( this.hashCode != object.hashCode() || !(object instanceof NaturalIdCacheKey that) ) { //hashCode is part of this check since it is pre-calculated and hash must match for equals to be true return false; } - return Objects.equals( entityName, other.entityName ) - && Objects.equals( tenantId, other.tenantId ) - && Objects.deepEquals( this.naturalIdValues, other.naturalIdValues ); + else { + return Objects.equals( this.entityName, that.entityName ) + && Objects.equals( this.tenantId, that.tenantId ) + && Objects.deepEquals( this.naturalIdValues, that.naturalIdValues ); + } } @Override @@ -104,7 +105,7 @@ public String toString() { // are not simply based on a single value like primary keys. // The only sane way to differentiate the keys is to include // the disassembled values in the string. - final StringBuilder string = + final var string = new StringBuilder().append( entityName ) .append( "##NaturalId[" ); if ( naturalIdValues instanceof Object[] values ) { diff --git a/hibernate-core/src/main/java/org/hibernate/cache/internal/NoCachingTransactionSynchronizationImpl.java b/hibernate-core/src/main/java/org/hibernate/cache/internal/NoCachingTransactionSynchronizationImpl.java index 97741caa7cc0..006b065d7664 100644 --- a/hibernate-core/src/main/java/org/hibernate/cache/internal/NoCachingTransactionSynchronizationImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/cache/internal/NoCachingTransactionSynchronizationImpl.java @@ -13,7 +13,7 @@ public class NoCachingTransactionSynchronizationImpl implements CacheTransaction public static final NoCachingTransactionSynchronizationImpl INSTANCE = new NoCachingTransactionSynchronizationImpl(); private NoCachingTransactionSynchronizationImpl() { - + //noop } @Override @@ -23,16 +23,16 @@ public long getCachingTimestamp() { @Override public void transactionJoined() { - + //noop } @Override public void transactionCompleting() { - + //noop } @Override public void transactionCompleted(boolean successful) { - + //noop } } diff --git a/hibernate-core/src/main/java/org/hibernate/cache/internal/QueryResultsCacheImpl.java b/hibernate-core/src/main/java/org/hibernate/cache/internal/QueryResultsCacheImpl.java index 3f9f8b1f1b0f..f74c0323c174 100644 --- a/hibernate-core/src/main/java/org/hibernate/cache/internal/QueryResultsCacheImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/cache/internal/QueryResultsCacheImpl.java @@ -9,14 +9,12 @@ import java.util.List; import java.util.Set; -import org.hibernate.HibernateException; import org.hibernate.cache.spi.QueryKey; import org.hibernate.cache.spi.QueryResultsCache; import org.hibernate.cache.spi.QueryResultsRegion; import org.hibernate.cache.spi.TimestampsCache; import org.hibernate.engine.spi.SharedSessionContractImplementor; import org.hibernate.event.monitor.spi.EventMonitor; -import org.hibernate.event.monitor.spi.DiagnosticEvent; import static org.hibernate.cache.spi.SecondLevelCacheLogger.L2CACHE_LOGGER; @@ -33,6 +31,10 @@ public class QueryResultsCacheImpl implements QueryResultsCache { private final QueryResultsRegion cacheRegion; private final TimestampsCache timestampsCache; + private record CacheItem(long timestamp, List results) + implements Serializable { + } + QueryResultsCacheImpl( QueryResultsRegion cacheRegion, TimestampsCache timestampsCache) { @@ -49,22 +51,19 @@ public QueryResultsRegion getRegion() { public boolean put( final QueryKey key, final List results, - final SharedSessionContractImplementor session) throws HibernateException { + final SharedSessionContractImplementor session) { + final var synchronization = session.getCacheTransactionSynchronization(); if ( L2CACHE_LOGGER.isTraceEnabled() ) { L2CACHE_LOGGER.cachingQueryResults( cacheRegion.getName(), - session.getCacheTransactionSynchronization().getCachingTimestamp() ); + synchronization.getCachingTimestamp() ); } - - final CacheItem cacheItem = new CacheItem( - session.getCacheTransactionSynchronization().getCachingTimestamp(), - deepCopy( results ) - ); - - final EventMonitor eventMonitor = session.getEventMonitor(); - final DiagnosticEvent cachePutEvent = eventMonitor.beginCachePutEvent(); + final var eventMonitor = session.getEventMonitor(); + final var cachePutEvent = eventMonitor.beginCachePutEvent(); + final var listenerManager = session.getEventListenerManager(); + final var cacheItem = new CacheItem( synchronization.getCachingTimestamp(), deepCopy( results ) ); try { - session.getEventListenerManager().cachePutStart(); + listenerManager.cachePutStart(); cacheRegion.putIntoCache( key, cacheItem, session ); } finally { @@ -75,9 +74,8 @@ public boolean put( true, EventMonitor.CacheActionDescription.QUERY_RESULT ); - session.getEventListenerManager().cachePutEnd(); + listenerManager.cachePutEnd(); } - return true; } @@ -89,13 +87,13 @@ private static List deepCopy(List results) { public List get( final QueryKey key, final Set spaces, - final SharedSessionContractImplementor session) throws HibernateException { + final SharedSessionContractImplementor session) { final boolean loggerTraceEnabled = L2CACHE_LOGGER.isTraceEnabled(); if ( loggerTraceEnabled ) { L2CACHE_LOGGER.checkingCachedQueryResults( cacheRegion.getName() ); } - final CacheItem cacheItem = getCachedData( key, session ); + final var cacheItem = getCachedData( key, session ); if ( cacheItem == null ) { if ( loggerTraceEnabled ) { L2CACHE_LOGGER.queryResultsNotFound(); @@ -122,14 +120,14 @@ public List get( public List get( final QueryKey key, final String[] spaces, - final SharedSessionContractImplementor session) throws HibernateException { + final SharedSessionContractImplementor session) { final boolean loggerTraceEnabled = L2CACHE_LOGGER.isTraceEnabled(); if ( loggerTraceEnabled ) { L2CACHE_LOGGER.checkingCachedQueryResults( cacheRegion.getName() ); } - final CacheItem cacheItem = getCachedData( key, session ); + final var cacheItem = getCachedData( key, session ); if ( cacheItem == null ) { if ( loggerTraceEnabled ) { L2CACHE_LOGGER.queryResultsNotFound(); @@ -152,37 +150,29 @@ public List get( } private CacheItem getCachedData(QueryKey key, SharedSessionContractImplementor session) { - CacheItem cachedItem = null; - final EventMonitor eventMonitor = session.getEventMonitor(); - final DiagnosticEvent cacheGetEvent = eventMonitor.beginCacheGetEvent(); + final var eventMonitor = session.getEventMonitor(); + final var cacheGetEvent = eventMonitor.beginCacheGetEvent(); + final var eventListenerManager = session.getEventListenerManager(); + boolean success = false; try { - session.getEventListenerManager().cacheGetStart(); - cachedItem = (CacheItem) cacheRegion.getFromCache( key, session ); + eventListenerManager.cacheGetStart(); + final var item = (CacheItem) cacheRegion.getFromCache( key, session ); + success = item != null; + return item; } finally { eventMonitor.completeCacheGetEvent( cacheGetEvent, session, cacheRegion, - cachedItem != null + success ); - session.getEventListenerManager().cacheGetEnd( cachedItem != null ); + eventListenerManager.cacheGetEnd( success ); } - return cachedItem; } @Override public String toString() { return "QueryResultsCache(" + cacheRegion.getName() + ')'; } - - static class CacheItem implements Serializable { - private final Long timestamp; - private final List results; - - CacheItem(long timestamp, List results) { - this.timestamp = Long.valueOf( timestamp ); - this.results = results; - } - } } diff --git a/hibernate-core/src/main/java/org/hibernate/cache/internal/RegionFactoryInitiator.java b/hibernate-core/src/main/java/org/hibernate/cache/internal/RegionFactoryInitiator.java index 9660bb4ca803..669db9a32630 100644 --- a/hibernate-core/src/main/java/org/hibernate/cache/internal/RegionFactoryInitiator.java +++ b/hibernate-core/src/main/java/org/hibernate/cache/internal/RegionFactoryInitiator.java @@ -4,7 +4,6 @@ */ package org.hibernate.cache.internal; -import java.util.Collection; import java.util.Map; import java.util.Properties; @@ -12,14 +11,16 @@ import org.hibernate.boot.registry.selector.spi.StrategySelector; import org.hibernate.cache.CacheException; import org.hibernate.cache.spi.RegionFactory; -import org.hibernate.cfg.AvailableSettings; import org.hibernate.internal.CoreLogging; import org.hibernate.internal.CoreMessageLogger; -import org.hibernate.internal.util.config.ConfigurationHelper; import org.hibernate.service.spi.ServiceRegistryImplementor; import static java.lang.Boolean.FALSE; import static java.lang.Boolean.TRUE; +import static org.hibernate.cfg.CacheSettings.CACHE_REGION_FACTORY; +import static org.hibernate.cfg.CacheSettings.USE_QUERY_CACHE; +import static org.hibernate.cfg.CacheSettings.USE_SECOND_LEVEL_CACHE; +import static org.hibernate.internal.util.config.ConfigurationHelper.getBooleanWrapper; /** * Initiator for the {@link RegionFactory} service. @@ -42,7 +43,7 @@ public Class getServiceInitiated() { @Override public RegionFactory initiateService(Map configurationValues, ServiceRegistryImplementor registry) { - final RegionFactory regionFactory = resolveRegionFactory( configurationValues, registry ); + final var regionFactory = resolveRegionFactory( configurationValues, registry ); if ( regionFactory instanceof NoCachingRegionFactory ) { LOG.noRegionFactory(); } @@ -54,16 +55,16 @@ public RegionFactory initiateService(Map configurationValues, Se protected RegionFactory resolveRegionFactory(Map configurationValues, ServiceRegistryImplementor registry) { - final Properties properties = new Properties(); + final var properties = new Properties(); properties.putAll( configurationValues ); - final Boolean useSecondLevelCache = ConfigurationHelper.getBooleanWrapper( - AvailableSettings.USE_SECOND_LEVEL_CACHE, + final Boolean useSecondLevelCache = getBooleanWrapper( + USE_SECOND_LEVEL_CACHE, configurationValues, null ); - final Boolean useQueryCache = ConfigurationHelper.getBooleanWrapper( - AvailableSettings.USE_QUERY_CACHE, + final Boolean useQueryCache = getBooleanWrapper( + USE_QUERY_CACHE, configurationValues, null ); @@ -77,10 +78,10 @@ protected RegionFactory resolveRegionFactory(Map configurationVal } } - final Object setting = configurationValues.get( AvailableSettings.CACHE_REGION_FACTORY ); + final Object setting = configurationValues.get( CACHE_REGION_FACTORY ); - final StrategySelector selector = registry.requireService( StrategySelector.class ); - final Collection> implementors = selector.getRegisteredStrategyImplementors( RegionFactory.class ); + final var selector = registry.requireService( StrategySelector.class ); + final var implementors = selector.getRegisteredStrategyImplementors( RegionFactory.class ); if ( setting == null && implementors.size() != 1 ) { // if either is explicitly defined as TRUE we need a RegionFactory @@ -89,7 +90,7 @@ protected RegionFactory resolveRegionFactory(Map configurationVal } } - final RegionFactory regionFactory = registry.requireService( StrategySelector.class ).resolveStrategy( + final var regionFactory = selector.resolveStrategy( RegionFactory.class, setting, (RegionFactory) null, @@ -101,15 +102,15 @@ protected RegionFactory resolveRegionFactory(Map configurationVal } - final RegionFactory fallback = getFallback( configurationValues, registry ); + final var fallback = getFallback( configurationValues, registry ); if ( fallback != null ) { return fallback; } if ( implementors.size() == 1 ) { - final RegionFactory registeredFactory = selector.resolveStrategy( RegionFactory.class, implementors.iterator().next() ); - configurationValues.put( AvailableSettings.CACHE_REGION_FACTORY, registeredFactory ); - configurationValues.put( AvailableSettings.USE_SECOND_LEVEL_CACHE, "true" ); + final var registeredFactory = selector.resolveStrategy( RegionFactory.class, implementors.iterator().next() ); + configurationValues.put( CACHE_REGION_FACTORY, registeredFactory ); + configurationValues.put( USE_SECOND_LEVEL_CACHE, "true" ); return registeredFactory; } else { diff --git a/hibernate-core/src/main/java/org/hibernate/cache/internal/StrategyCreatorRegionFactoryImpl.java b/hibernate-core/src/main/java/org/hibernate/cache/internal/StrategyCreatorRegionFactoryImpl.java index 8a4645471c6c..60a7b2bf2839 100644 --- a/hibernate-core/src/main/java/org/hibernate/cache/internal/StrategyCreatorRegionFactoryImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/cache/internal/StrategyCreatorRegionFactoryImpl.java @@ -12,13 +12,10 @@ import org.hibernate.cache.spi.RegionFactory; import org.hibernate.service.spi.ServiceException; -import org.jboss.logging.Logger; - /** * @author Steve Ebersole */ public class StrategyCreatorRegionFactoryImpl implements StrategyCreator { - private static final Logger log = Logger.getLogger( StrategyCreatorRegionFactoryImpl.class ); private final Properties properties; @@ -31,12 +28,12 @@ public RegionFactory create(Class strategyClass) { assert RegionFactory.class.isAssignableFrom( strategyClass ); // first look for a constructor accepting Properties - final RegionFactory regionFactoryWithProperties = instantiateWithProperties( strategyClass, Properties.class ); + final var regionFactoryWithProperties = instantiateWithProperties( strategyClass, Properties.class ); if ( regionFactoryWithProperties != null ) { return regionFactoryWithProperties; } // next try Map - final RegionFactory regionFactoryWithMap = instantiateWithProperties( strategyClass, Map.class ); + final var regionFactoryWithMap = instantiateWithProperties( strategyClass, Map.class ); if ( regionFactoryWithMap != null ) { return regionFactoryWithMap; } @@ -54,7 +51,6 @@ private RegionFactory instantiateWithProperties(Class s return strategyClass.getConstructor( propertiesClass ).newInstance( properties ); } catch ( NoSuchMethodException e ) { - log.debugf( "RegionFactory impl [%s] did not provide constructor accepting Properties", strategyClass.getName() ); return null; } catch (IllegalAccessException | InstantiationException | InvocationTargetException e) { diff --git a/hibernate-core/src/main/java/org/hibernate/cache/internal/TimestampsCacheDisabledImpl.java b/hibernate-core/src/main/java/org/hibernate/cache/internal/TimestampsCacheDisabledImpl.java index ad1c4d9842c4..8449619f9b2b 100644 --- a/hibernate-core/src/main/java/org/hibernate/cache/internal/TimestampsCacheDisabledImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/cache/internal/TimestampsCacheDisabledImpl.java @@ -10,8 +10,6 @@ import org.hibernate.cache.spi.TimestampsRegion; import org.hibernate.engine.spi.SharedSessionContractImplementor; -import org.jboss.logging.Logger; - /** * TimestampsRegionAccess implementation for cases where query results caching * (or second level caching overall) is disabled. @@ -19,8 +17,6 @@ * @author Steve Ebersole */ public class TimestampsCacheDisabledImpl implements TimestampsCache { - private static final Logger log = Logger.getLogger( TimestampsCacheDisabledImpl.class ); - @Override public TimestampsRegion getRegion() { return null; @@ -28,12 +24,12 @@ public TimestampsRegion getRegion() { @Override public void preInvalidate(String[] spaces, SharedSessionContractImplementor session) { - log.trace( "TimestampsRegionAccess#preInvalidate - disabled" ); + //noop } @Override public void invalidate(String[] spaces, SharedSessionContractImplementor session) { - log.trace( "TimestampsRegionAccess#invalidate - disabled" ); + //noop } @Override @@ -41,7 +37,7 @@ public boolean isUpToDate( String[] spaces, Long timestamp, SharedSessionContractImplementor session) { - log.trace( "TimestampsRegionAccess#isUpToDate - disabled" ); + //noop return false; } @@ -50,7 +46,7 @@ public boolean isUpToDate( Collection spaces, Long timestamp, SharedSessionContractImplementor session) { - log.trace( "TimestampsRegionAccess#isUpToDate - disabled" ); + //noop return false; } } diff --git a/hibernate-core/src/main/java/org/hibernate/cache/internal/TimestampsCacheEnabledImpl.java b/hibernate-core/src/main/java/org/hibernate/cache/internal/TimestampsCacheEnabledImpl.java index 2021f1a26f6a..e837369abc4d 100644 --- a/hibernate-core/src/main/java/org/hibernate/cache/internal/TimestampsCacheEnabledImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/cache/internal/TimestampsCacheEnabledImpl.java @@ -6,14 +6,9 @@ import java.util.Collection; -import org.hibernate.cache.spi.RegionFactory; import org.hibernate.cache.spi.TimestampsCache; import org.hibernate.cache.spi.TimestampsRegion; -import org.hibernate.engine.spi.SessionEventListenerManager; -import org.hibernate.engine.spi.SessionFactoryImplementor; import org.hibernate.engine.spi.SharedSessionContractImplementor; -import org.hibernate.event.monitor.spi.EventMonitor; -import org.hibernate.event.monitor.spi.DiagnosticEvent; import org.hibernate.stat.spi.StatisticsImplementor; import static org.hibernate.cache.spi.SecondLevelCacheLogger.L2CACHE_LOGGER; @@ -42,21 +37,21 @@ public TimestampsRegion getRegion() { public void preInvalidate( String[] spaces, SharedSessionContractImplementor session) { - final SessionFactoryImplementor factory = session.getFactory(); - final RegionFactory regionFactory = factory.getCache().getRegionFactory(); - final StatisticsImplementor statistics = factory.getStatistics(); + final var factory = session.getFactory(); + final var regionFactory = factory.getCache().getRegionFactory(); + final var statistics = factory.getStatistics(); final boolean stats = statistics.isStatisticsEnabled(); final Long timestamp = regionFactory.nextTimestamp() + regionFactory.getTimeout(); - final SessionEventListenerManager eventListenerManager = session.getEventListenerManager(); - final EventMonitor eventMonitor = session.getEventMonitor(); + final var eventListenerManager = session.getEventListenerManager(); + final var eventMonitor = session.getEventMonitor(); final boolean traceEnabled = L2CACHE_LOGGER.isTraceEnabled(); for ( String space : spaces ) { if ( traceEnabled ) { L2CACHE_LOGGER.preInvalidatingSpace( space, timestamp ); } - final DiagnosticEvent cachePutEvent = eventMonitor.beginCachePutEvent(); + final var cachePutEvent = eventMonitor.beginCachePutEvent(); try { eventListenerManager.cachePutStart(); @@ -85,21 +80,21 @@ public void preInvalidate( public void invalidate( String[] spaces, SharedSessionContractImplementor session) { - final SessionFactoryImplementor factory = session.getFactory(); - final StatisticsImplementor statistics = factory.getStatistics(); + final var factory = session.getFactory(); + final var statistics = factory.getStatistics(); final boolean stats = statistics.isStatisticsEnabled(); final Long timestamp = factory.getCache().getRegionFactory().nextTimestamp(); - final SessionEventListenerManager eventListenerManager = session.getEventListenerManager(); - final EventMonitor eventMonitor = session.getEventMonitor(); + final var eventListenerManager = session.getEventListenerManager(); + final var eventMonitor = session.getEventMonitor(); final boolean traceEnabled = L2CACHE_LOGGER.isTraceEnabled(); for ( String space : spaces ) { if ( traceEnabled ) { L2CACHE_LOGGER.invalidatingSpace( space, timestamp ); } - final DiagnosticEvent cachePutEvent = eventMonitor.beginCachePutEvent(); + final var cachePutEvent = eventMonitor.beginCachePutEvent(); try { eventListenerManager.cachePutStart(); timestampsRegion.putIntoCache( space, timestamp, session ); @@ -126,7 +121,7 @@ public boolean isUpToDate( String[] spaces, Long timestamp, SharedSessionContractImplementor session) { - final StatisticsImplementor statistics = session.getFactory().getStatistics(); + final var statistics = session.getFactory().getStatistics(); for ( String space : spaces ) { if ( isSpaceOutOfDate( space, timestamp, session, statistics ) ) { return false; @@ -163,7 +158,7 @@ public boolean isUpToDate( Collection spaces, Long timestamp, SharedSessionContractImplementor session) { - final StatisticsImplementor statistics = session.getFactory().getStatistics(); + final var statistics = session.getFactory().getStatistics(); for ( String space : spaces ) { if ( isSpaceOutOfDate( space, timestamp, session, statistics ) ) { return false; @@ -174,17 +169,18 @@ public boolean isUpToDate( private Long getLastUpdateTimestampForSpace(String space, SharedSessionContractImplementor session) { boolean found = false; - final EventMonitor eventMonitor = session.getEventMonitor(); - final DiagnosticEvent cacheGetEvent = eventMonitor.beginCacheGetEvent(); + final var eventMonitor = session.getEventMonitor(); + final var eventListenerManager = session.getEventListenerManager(); + final var cacheGetEvent = eventMonitor.beginCacheGetEvent(); try { - session.getEventListenerManager().cacheGetStart(); + eventListenerManager.cacheGetStart(); final Long timestamp = (Long) timestampsRegion.getFromCache( space, session ); found = timestamp != null; return timestamp; } finally { eventMonitor.completeCacheGetEvent( cacheGetEvent, session, timestampsRegion, found ); - session.getEventListenerManager().cacheGetEnd( found ); + eventListenerManager.cacheGetEnd( found ); } } diff --git a/hibernate-core/src/main/java/org/hibernate/cache/spi/QueryKey.java b/hibernate-core/src/main/java/org/hibernate/cache/spi/QueryKey.java index 3864f1519a00..c9a596b2b541 100644 --- a/hibernate-core/src/main/java/org/hibernate/cache/spi/QueryKey.java +++ b/hibernate-core/src/main/java/org/hibernate/cache/spi/QueryKey.java @@ -5,6 +5,7 @@ package org.hibernate.cache.spi; import java.io.IOException; +import java.io.Serial; import java.io.Serializable; import java.util.Arrays; import java.util.Objects; @@ -44,9 +45,7 @@ public static QueryKey from( // // todo (6.0) : should limited (first/max) results be cacheable? // todo (6.0) : should filtered results be cacheable? - final Limit limitToUse = limit == null ? Limit.NONE : limit; - return new QueryKey( sqlQueryString, parameterBindings.generateQueryKeyMemento( session ), @@ -56,7 +55,6 @@ public static QueryKey from( ); } - private final String sqlQueryString; private final ParameterBindingsMemento parameterBindingsMemento; private final Integer firstRow; @@ -70,12 +68,12 @@ public static QueryKey from( private transient int hashCode; public QueryKey( - String sql, + String sqlQueryString, ParameterBindingsMemento parameterBindingsMemento, Integer firstRow, Integer maxRows, Set enabledFilterNames) { - this.sqlQueryString = sql; + this.sqlQueryString = sqlQueryString; this.parameterBindingsMemento = parameterBindingsMemento; this.firstRow = firstRow; this.maxRows = maxRows; @@ -91,15 +89,18 @@ public QueryKey( * @throws IOException Thrown by normal deserialization * @throws ClassNotFoundException Thrown by normal deserialization */ - private void readObject(java.io.ObjectInputStream in) throws IOException, ClassNotFoundException { + @Serial + private void readObject(java.io.ObjectInputStream in) + throws IOException, ClassNotFoundException { in.defaultReadObject(); - this.hashCode = generateHashCode(); + hashCode = generateHashCode(); } private int generateHashCode() { int result = 13; result = 37 * result + sqlQueryString.hashCode(); - // Don't include the firstRow and maxRows in the hash as these values are rarely useful for query caching + // Don't include the firstRow and maxRows in the hash + // as these values are rarely useful for query caching // result = 37 * result + ( firstRow==null ? 0 : firstRow ); // result = 37 * result + ( maxRows==null ? 0 : maxRows ); result = 37 * result + parameterBindingsMemento.hashCode(); @@ -108,38 +109,14 @@ private int generateHashCode() { } @Override - @SuppressWarnings({"RedundantIfStatement", "EqualsWhichDoesntCheckParameterClass"}) public boolean equals(Object other) { - // it should never be another type, so skip the instanceof check and just do the cast - final QueryKey that; - - try { - that = (QueryKey) other; - } - catch (ClassCastException cce) { - // treat this as the exception case - return false; - } - - if ( ! Objects.equals( sqlQueryString, that.sqlQueryString ) ) { - return false; - } - - if ( ! Objects.equals( firstRow, that.firstRow ) - || ! Objects.equals( maxRows, that.maxRows ) ) { - return false; - } - - // Set's `#equals` impl does a deep check, so `Objects#equals` is a good check - if ( ! Objects.equals( parameterBindingsMemento, that.parameterBindingsMemento ) ) { - return false; - } - - if ( ! Arrays.equals( enabledFilterNames, that.enabledFilterNames ) ) { - return false; - } - - return true; + return other instanceof QueryKey that + && Objects.equals( this.sqlQueryString, that.sqlQueryString ) + && Objects.equals( this.firstRow, that.firstRow ) + && Objects.equals( this.maxRows, that.maxRows ) + // Set's `#equals` impl does a deep check, so `Objects#equals` is a good check + && Objects.equals( this.parameterBindingsMemento, that.parameterBindingsMemento ) + && Arrays.equals( this.enabledFilterNames, that.enabledFilterNames ); } @Override diff --git a/hibernate-core/src/main/java/org/hibernate/cache/spi/entry/StructuredCacheEntry.java b/hibernate-core/src/main/java/org/hibernate/cache/spi/entry/StructuredCacheEntry.java index e29ba01b8418..799e3d747a9e 100644 --- a/hibernate-core/src/main/java/org/hibernate/cache/spi/entry/StructuredCacheEntry.java +++ b/hibernate-core/src/main/java/org/hibernate/cache/spi/entry/StructuredCacheEntry.java @@ -51,7 +51,7 @@ public Object destructure(Object structured, SessionFactoryImplementor factory) @Override public Object structure(Object item) { - final CacheEntry entry = (CacheEntry) item; + final var entry = (CacheEntry) item; final String[] names = persister.getPropertyNames(); final Map map = new HashMap<>( names.length + 3, 1f ); map.put( SUBCLASS_KEY, entry.getSubclass() ); diff --git a/hibernate-core/src/main/java/org/hibernate/cache/spi/entry/StructuredCollectionCacheEntry.java b/hibernate-core/src/main/java/org/hibernate/cache/spi/entry/StructuredCollectionCacheEntry.java index 3d4e47822520..4b7ba3fedcc4 100644 --- a/hibernate-core/src/main/java/org/hibernate/cache/spi/entry/StructuredCollectionCacheEntry.java +++ b/hibernate-core/src/main/java/org/hibernate/cache/spi/entry/StructuredCollectionCacheEntry.java @@ -23,14 +23,14 @@ public class StructuredCollectionCacheEntry implements CacheEntryStructure { @Override public Object structure(Object item) { - final CollectionCacheEntry entry = (CollectionCacheEntry) item; + final var entry = (CollectionCacheEntry) item; return Arrays.asList( entry.getState() ); } @Override public Object destructure(Object structured, SessionFactoryImplementor factory) { - final List list = (List) structured; - return new CollectionCacheEntry( list.toArray( new Serializable[list.size()] ) ); + final var list = (List) structured; + return new CollectionCacheEntry( list.toArray( Serializable[]::new ) ); } private StructuredCollectionCacheEntry() { diff --git a/hibernate-core/src/main/java/org/hibernate/cache/spi/entry/StructuredMapCacheEntry.java b/hibernate-core/src/main/java/org/hibernate/cache/spi/entry/StructuredMapCacheEntry.java index 1b04628b2000..646111da2c35 100644 --- a/hibernate-core/src/main/java/org/hibernate/cache/spi/entry/StructuredMapCacheEntry.java +++ b/hibernate-core/src/main/java/org/hibernate/cache/spi/entry/StructuredMapCacheEntry.java @@ -8,7 +8,8 @@ import java.util.Map; import org.hibernate.engine.spi.SessionFactoryImplementor; -import org.hibernate.internal.util.collections.CollectionHelper; + +import static org.hibernate.internal.util.collections.CollectionHelper.mapOfSize; /** * Structured CacheEntry format for persistent Maps. @@ -22,13 +23,11 @@ public class StructuredMapCacheEntry implements CacheEntryStructure { public static final StructuredMapCacheEntry INSTANCE = new StructuredMapCacheEntry(); @Override - @SuppressWarnings("unchecked") public Object structure(Object item) { - final CollectionCacheEntry entry = (CollectionCacheEntry) item; + final var entry = (CollectionCacheEntry) item; final Serializable[] state = entry.getState(); - final Map map = CollectionHelper.mapOfSize( state.length ); - int i = 0; - while ( i < state.length ) { + final Map map = mapOfSize( state.length ); + for ( int i = 0; i < state.length; ) { map.put( state[i++], state[i++] ); } return map; @@ -36,10 +35,10 @@ public Object structure(Object item) { @Override public Object destructure(Object structured, SessionFactoryImplementor factory) { - final Map map = (Map) structured; + final var map = (Map) structured; final Serializable[] state = new Serializable[ map.size()*2 ]; int i = 0; - for ( Map.Entry me : map.entrySet() ) { + for ( var me : map.entrySet() ) { state[i++] = (Serializable) me.getKey(); state[i++] = (Serializable) me.getValue(); } diff --git a/hibernate-core/src/main/java/org/hibernate/cache/spi/support/AbstractDomainDataRegion.java b/hibernate-core/src/main/java/org/hibernate/cache/spi/support/AbstractDomainDataRegion.java index 4ddddbc05ce0..952974a29c55 100644 --- a/hibernate-core/src/main/java/org/hibernate/cache/spi/support/AbstractDomainDataRegion.java +++ b/hibernate-core/src/main/java/org/hibernate/cache/spi/support/AbstractDomainDataRegion.java @@ -4,8 +4,6 @@ */ package org.hibernate.cache.spi.support; -import java.util.Collections; -import java.util.List; import java.util.Map; import org.hibernate.cache.CacheException; @@ -22,11 +20,13 @@ import org.hibernate.cache.spi.access.EntityDataAccess; import org.hibernate.cache.spi.access.NaturalIdDataAccess; import org.hibernate.engine.spi.SessionFactoryImplementor; -import org.hibernate.internal.util.collections.CollectionHelper; import org.hibernate.metamodel.model.domain.NavigableRole; +import static java.util.Collections.emptyMap; +import static java.util.Collections.unmodifiableMap; import static org.hibernate.cache.spi.SecondLevelCacheLogger.L2CACHE_LOGGER; +import static org.hibernate.internal.util.collections.CollectionHelper.mapOfSize; /** * @author Steve Ebersole @@ -48,12 +48,12 @@ public AbstractDomainDataRegion( // super( regionFactory.qualify( regionConfig.getRegionName() ), regionFactory ); super( regionConfig.getRegionName(), regionFactory ); - this.sessionFactory = buildingContext.getSessionFactory(); + sessionFactory = buildingContext.getSessionFactory(); if ( defaultKeysFactory == null ) { defaultKeysFactory = DefaultCacheKeysFactory.INSTANCE; } - this.effectiveKeysFactory = buildingContext.getEnforcedCacheKeysFactory() != null + effectiveKeysFactory = buildingContext.getEnforcedCacheKeysFactory() != null ? buildingContext.getEnforcedCacheKeysFactory() : defaultKeysFactory; } @@ -70,9 +70,9 @@ protected void completeInstantiation( L2CACHE_LOGGER.tracef( "DomainDataRegion created [%s]; key-factory = %s", regionConfig.getRegionName(), effectiveKeysFactory ); - this.entityDataAccessMap = generateEntityDataAccessMap( regionConfig ); - this.naturalIdDataAccessMap = generateNaturalIdDataAccessMap( regionConfig ); - this.collectionDataAccessMap = generateCollectionDataAccessMap( regionConfig ); + entityDataAccessMap = generateEntityDataAccessMap( regionConfig ); + naturalIdDataAccessMap = generateNaturalIdDataAccessMap( regionConfig ); + collectionDataAccessMap = generateCollectionDataAccessMap( regionConfig ); } @@ -86,7 +86,7 @@ public CacheKeysFactory getEffectiveKeysFactory() { @Override public EntityDataAccess getEntityDataAccess(NavigableRole rootEntityRole) { - final EntityDataAccess access = entityDataAccessMap.get( rootEntityRole ); + final var access = entityDataAccessMap.get( rootEntityRole ); if ( access == null ) { throw new IllegalArgumentException( "Caching was not configured for entity: " + rootEntityRole.getFullPath() ); } @@ -96,7 +96,7 @@ public EntityDataAccess getEntityDataAccess(NavigableRole rootEntityRole) { @Override public NaturalIdDataAccess getNaturalIdDataAccess(NavigableRole rootEntityRole) { - final NaturalIdDataAccess access = naturalIdDataAccessMap.get( rootEntityRole ); + final var access = naturalIdDataAccessMap.get( rootEntityRole ); if ( access == null ) { throw new IllegalArgumentException( "Caching was not configured for entity natural id: " + rootEntityRole.getFullPath() ); } @@ -105,7 +105,7 @@ public NaturalIdDataAccess getNaturalIdDataAccess(NavigableRole rootEntityRole) @Override public CollectionDataAccess getCollectionDataAccess(NavigableRole collectionRole) { - final CollectionDataAccess access = collectionDataAccessMap.get( collectionRole ); + final var access = collectionDataAccessMap.get( collectionRole ); if ( access == null ) { throw new IllegalArgumentException( "Caching was not configured for collection: " + collectionRole.getFullPath() ); } @@ -121,68 +121,57 @@ public CollectionDataAccess getCollectionDataAccess(NavigableRole collectionRole private Map generateEntityDataAccessMap( DomainDataRegionConfig regionConfig) { - final List entityCaching = regionConfig.getEntityCaching(); + final var entityCaching = regionConfig.getEntityCaching(); if ( entityCaching.isEmpty() ) { - return Collections.emptyMap(); + return emptyMap(); } - final Map accessMap = CollectionHelper.mapOfSize( entityCaching.size() ); - for ( EntityDataCachingConfig entityAccessConfig : entityCaching ) { - accessMap.put( - entityAccessConfig.getNavigableRole(), - generateEntityAccess( entityAccessConfig ) - ); + final Map accessMap = mapOfSize( entityCaching.size() ); + for ( var entityAccessConfig : entityCaching ) { + accessMap.put( entityAccessConfig.getNavigableRole(), + generateEntityAccess( entityAccessConfig ) ); } - - return Collections.unmodifiableMap( accessMap ); + return unmodifiableMap( accessMap ); } private Map generateNaturalIdDataAccessMap(DomainDataRegionConfig regionConfig) { - final List naturalIdCaching = regionConfig.getNaturalIdCaching(); + final var naturalIdCaching = regionConfig.getNaturalIdCaching(); if ( naturalIdCaching.isEmpty() ) { - return Collections.emptyMap(); + return emptyMap(); } - final Map accessMap = CollectionHelper.mapOfSize( naturalIdCaching.size() ); - for ( NaturalIdDataCachingConfig naturalIdAccessConfig : naturalIdCaching ) { - accessMap.put( - naturalIdAccessConfig.getNavigableRole(), - generateNaturalIdAccess( naturalIdAccessConfig ) - ); + final Map accessMap = mapOfSize( naturalIdCaching.size() ); + for ( var naturalIdAccessConfig : naturalIdCaching ) { + accessMap.put( naturalIdAccessConfig.getNavigableRole(), + generateNaturalIdAccess( naturalIdAccessConfig ) ); } - - return Collections.unmodifiableMap( accessMap ); + return unmodifiableMap( accessMap ); } private Map generateCollectionDataAccessMap( DomainDataRegionConfig regionConfig) { - final List collectionCaching = regionConfig.getCollectionCaching(); + final var collectionCaching = regionConfig.getCollectionCaching(); if ( collectionCaching.isEmpty() ) { - return Collections.emptyMap(); + return emptyMap(); } - final Map accessMap = CollectionHelper.mapOfSize( collectionCaching.size() ); - for ( CollectionDataCachingConfig cachingConfig : collectionCaching ) { - accessMap.put( - cachingConfig.getNavigableRole(), - generateCollectionAccess( cachingConfig ) - ); + final Map accessMap = mapOfSize( collectionCaching.size() ); + for ( var cachingConfig : collectionCaching ) { + accessMap.put( cachingConfig.getNavigableRole(), + generateCollectionAccess( cachingConfig ) ); } - - return Collections.unmodifiableMap( accessMap ); + return unmodifiableMap( accessMap ); } @Override public void clear() { - for ( EntityDataAccess cacheAccess : entityDataAccessMap.values() ) { + for ( var cacheAccess : entityDataAccessMap.values() ) { cacheAccess.evictAll(); } - - for ( NaturalIdDataAccess cacheAccess : naturalIdDataAccessMap.values() ) { + for ( var cacheAccess : naturalIdDataAccessMap.values() ) { cacheAccess.evictAll(); } - - for ( CollectionDataAccess cacheAccess : collectionDataAccessMap.values() ) { + for ( var cacheAccess : collectionDataAccessMap.values() ) { cacheAccess.evictAll(); } } @@ -220,15 +209,13 @@ protected void releaseDataAccess(CollectionDataAccess cacheAccess) { @Override public void destroy() throws CacheException { - for ( EntityDataAccess cacheAccess : entityDataAccessMap.values() ) { + for ( var cacheAccess : entityDataAccessMap.values() ) { releaseDataAccess( cacheAccess ); } - - for ( NaturalIdDataAccess cacheAccess : naturalIdDataAccessMap.values() ) { + for ( var cacheAccess : naturalIdDataAccessMap.values() ) { releaseDataAccess( cacheAccess ); } - - for ( CollectionDataAccess cacheAccess : collectionDataAccessMap.values() ) { + for ( var cacheAccess : collectionDataAccessMap.values() ) { releaseDataAccess( cacheAccess ); } } diff --git a/hibernate-core/src/main/java/org/hibernate/cache/spi/support/AbstractReadWriteAccess.java b/hibernate-core/src/main/java/org/hibernate/cache/spi/support/AbstractReadWriteAccess.java index 65f31ec56c78..539301feaa79 100644 --- a/hibernate-core/src/main/java/org/hibernate/cache/spi/support/AbstractReadWriteAccess.java +++ b/hibernate-core/src/main/java/org/hibernate/cache/spi/support/AbstractReadWriteAccess.java @@ -4,6 +4,7 @@ */ package org.hibernate.cache.spi.support; +import java.io.Serial; import java.io.Serializable; import java.util.Comparator; import java.util.Locale; @@ -13,7 +14,6 @@ import java.util.concurrent.locks.ReentrantReadWriteLock; import org.hibernate.cache.spi.DomainDataRegion; -import org.hibernate.cache.spi.RegionFactory; import org.hibernate.cache.spi.access.SoftLock; import org.hibernate.engine.spi.SharedSessionContractImplementor; @@ -37,7 +37,7 @@ protected AbstractReadWriteAccess( super( domainDataRegion, storageAccess ); } - protected abstract Comparator getVersionComparator(); + protected abstract Comparator getVersionComparator(); protected UUID uuid() { return uuid; @@ -68,8 +68,7 @@ public Object get(SharedSessionContractImplementor session, Object key) { } try { readLock.lock(); - final Lockable item = (Lockable) getStorageAccess().getFromCache( key, session ); - + final var item = (Lockable) getStorageAccess().getFromCache( key, session ); if ( item == null ) { if ( traceEnabled ) { L2CACHE_LOGGER.tracef( "Cache miss: region = '%s', key = '%s'", @@ -78,8 +77,7 @@ public Object get(SharedSessionContractImplementor session, Object key) { return null; } - final boolean readable = item.isReadable( session.getCacheTransactionSynchronization().getCachingTimestamp() ); - if ( readable ) { + if ( isReadable( session, item ) ) { if ( traceEnabled ) { L2CACHE_LOGGER.tracef( "Cache hit: region = '%s', key = '%s'", getRegion().getName(), key ); @@ -99,6 +97,10 @@ public Object get(SharedSessionContractImplementor session, Object key) { } } + private static boolean isReadable(SharedSessionContractImplementor session, Lockable item) { + return item.isReadable( session.getCacheTransactionSynchronization().getCachingTimestamp() ); + } + @Override public boolean putFromLoad( SharedSessionContractImplementor session, @@ -112,10 +114,8 @@ public boolean putFromLoad( getRegion().getName(), getAccessType(), key, value ); } writeLock.lock(); - Lockable item = (Lockable) getStorageAccess().getFromCache( key, session ); - - boolean writable = item == null || item.isWriteable( session.getCacheTransactionSynchronization().getCachingTimestamp(), version, getVersionComparator() ); - if ( writable ) { + final var item = (Lockable) getStorageAccess().getFromCache( key, session ); + if ( isWritable( session, version, item ) ) { getStorageAccess().putIntoCache( key, new Item( value, version, session.getCacheTransactionSynchronization().getCachingTimestamp() ), @@ -141,6 +141,12 @@ public boolean putFromLoad( } } + private boolean isWritable(SharedSessionContractImplementor session, Object version, Lockable item) { + return item == null + || item.isWriteable( session.getCacheTransactionSynchronization().getCachingTimestamp(), + version, getVersionComparator() ); + } + protected abstract AccessedDataClassification getAccessedDataClassification(); @Override @@ -157,17 +163,13 @@ public final boolean putFromLoad( public SoftLock lockItem(SharedSessionContractImplementor session, Object key, Object version) { try { writeLock.lock(); - - long timeout = getRegion().getRegionFactory().nextTimestamp() + getRegion().getRegionFactory().getTimeout(); + final long timeout = nextTimestamp() + getTimeout(); if ( L2CACHE_LOGGER.isTraceEnabled() ) { L2CACHE_LOGGER.tracef( "Locking cache item [region='%s' (%s)] : '%s' (timeout=%s, version=%s)", getRegion().getName(), getAccessType(), key, timeout, version ); } - - Lockable item = (Lockable) getStorageAccess().getFromCache( key, session ); - final SoftLockImpl lock = ( item == null ) - ? new SoftLockImpl( timeout, uuid, nextLockId(), version ) - : item.lock( timeout, uuid, nextLockId() ); + final var item = (Lockable) getStorageAccess().getFromCache( key, session ); + final var lock = lock( item, version, timeout ); getStorageAccess().putIntoCache( key, lock, session ); return lock; } @@ -176,6 +178,12 @@ public SoftLock lockItem(SharedSessionContractImplementor session, Object key, O } } + private SoftLockImpl lock(Lockable item, Object version, long timeout) { + return item == null + ? new SoftLockImpl( timeout, uuid, nextLockId(), version ) + : item.lock( timeout, uuid, nextLockId() ); + } + @Override public void unlockItem(SharedSessionContractImplementor session, Object key, SoftLock lock) { try { @@ -184,13 +192,12 @@ public void unlockItem(SharedSessionContractImplementor session, Object key, Sof getRegion().getName(), getAccessType(), key ); } writeLock.lock(); - Lockable item = (Lockable) getStorageAccess().getFromCache( key, session ); - + final var item = (Lockable) getStorageAccess().getFromCache( key, session ); if ( item != null && item.isUnlockable( lock ) ) { decrementLock( session, key, (SoftLockImpl) item ); } else { - handleLockExpiry( session, key, item ); + handleLockExpiry( session, key ); } } finally { @@ -198,21 +205,28 @@ public void unlockItem(SharedSessionContractImplementor session, Object key, Sof } } + long getTimeout() { + return getRegion().getRegionFactory().getTimeout(); + } + + long nextTimestamp() { + return getRegion().getRegionFactory().nextTimestamp(); + } + protected void decrementLock(SharedSessionContractImplementor session, Object key, SoftLockImpl lock) { - lock.unlock( getRegion().getRegionFactory().nextTimestamp() ); + lock.unlock( nextTimestamp() ); getStorageAccess().putIntoCache( key, lock, session ); } - protected void handleLockExpiry(SharedSessionContractImplementor session, Object key, Lockable lock) { + protected void handleLockExpiry(SharedSessionContractImplementor session, Object key) { L2CACHE_LOGGER.softLockedCacheExpired( getRegion().getName(), key ); L2CACHE_LOGGER.tracef( "Cached entry expired: %s", key ); - final RegionFactory regionFactory = getRegion().getRegionFactory(); - - // create new lock that times out immediately - long ts = regionFactory.nextTimestamp() + regionFactory.getTimeout(); - SoftLockImpl newLock = new SoftLockImpl( ts, uuid, nextLockId.getAndIncrement(), null ); - //newLock.unlock( ts ); - newLock.unlock( ts - regionFactory.getTimeout() ); + final var regionFactory = getRegion().getRegionFactory(); + // create a new lock that times out immediately + long timestamp = regionFactory.nextTimestamp() + regionFactory.getTimeout(); + final var newLock = new SoftLockImpl( timestamp, uuid, nextLockId.getAndIncrement(), null ); + //newLock.unlock( timestamp ); + newLock.unlock( timestamp - regionFactory.getTimeout() ); getStorageAccess().putIntoCache( key, newLock, session ); } @@ -271,6 +285,7 @@ public interface Lockable { * Wrapper type representing unlocked items. */ public final static class Item implements Serializable, Lockable { + @Serial private static final long serialVersionUID = 1L; private final Object value; private final Object version; @@ -345,6 +360,7 @@ public String toString() { */ public static class SoftLockImpl implements Serializable, Lockable, SoftLock { + @Serial private static final long serialVersionUID = 2L; private final UUID sourceUuid; @@ -414,11 +430,11 @@ public boolean isUnlockable(SoftLock lock) { } @Override - public boolean equals(Object o) { - if ( o == this ) { + public boolean equals(Object other) { + if ( other == this ) { return true; } - else if ( o instanceof SoftLockImpl that ) { + else if ( other instanceof SoftLockImpl that ) { return this.lockId == that.lockId && this.sourceUuid.equals( that.sourceUuid ); } diff --git a/hibernate-core/src/main/java/org/hibernate/cache/spi/support/CacheUtils.java b/hibernate-core/src/main/java/org/hibernate/cache/spi/support/CacheUtils.java deleted file mode 100644 index ec0da07f2e3b..000000000000 --- a/hibernate-core/src/main/java/org/hibernate/cache/spi/support/CacheUtils.java +++ /dev/null @@ -1,22 +0,0 @@ -/* - * SPDX-License-Identifier: Apache-2.0 - * Copyright Red Hat Inc. and Hibernate Authors - */ -package org.hibernate.cache.spi.support; - -import org.hibernate.boot.spi.SessionFactoryOptions; - -/** - * @author Steve Ebersole - */ -public class CacheUtils { - public static boolean isUnqualified(String regionName, SessionFactoryOptions options) { - final String prefix = options.getCacheRegionPrefix(); - if ( prefix == null ) { - return true; - } - else { - return !regionName.startsWith( prefix ); - } - } -} diff --git a/hibernate-core/src/main/java/org/hibernate/cache/spi/support/CollectionReadWriteAccess.java b/hibernate-core/src/main/java/org/hibernate/cache/spi/support/CollectionReadWriteAccess.java index a60c10482983..9c1ea00ab49d 100644 --- a/hibernate-core/src/main/java/org/hibernate/cache/spi/support/CollectionReadWriteAccess.java +++ b/hibernate-core/src/main/java/org/hibernate/cache/spi/support/CollectionReadWriteAccess.java @@ -14,7 +14,6 @@ import org.hibernate.cache.spi.access.SoftLock; import org.hibernate.engine.spi.SessionFactoryImplementor; import org.hibernate.engine.spi.SharedSessionContractImplementor; -import org.hibernate.metamodel.model.domain.NavigableRole; import org.hibernate.persister.collection.CollectionPersister; /** * Standard support for {@link CollectionDataAccess} @@ -24,8 +23,7 @@ * @author Steve Ebersole */ public class CollectionReadWriteAccess extends AbstractReadWriteAccess implements CollectionDataAccess { - private final NavigableRole collectionRole; - private final Comparator versionComparator; + private final Comparator versionComparator; private final CacheKeysFactory keysFactory; public CollectionReadWriteAccess( @@ -35,7 +33,6 @@ public CollectionReadWriteAccess( CollectionDataCachingConfig config) { super( region, storageAccess ); this.keysFactory = keysFactory; - this.collectionRole = config.getNavigableRole(); this.versionComparator = config.getOwnerVersionComparator(); } @@ -64,7 +61,7 @@ public Object getCacheKeyId(Object cacheKey) { } @Override - protected Comparator getVersionComparator() { + protected Comparator getVersionComparator() { return versionComparator; } diff --git a/hibernate-core/src/main/java/org/hibernate/cache/spi/support/DomainDataRegionTemplate.java b/hibernate-core/src/main/java/org/hibernate/cache/spi/support/DomainDataRegionTemplate.java index 9d77619e9e06..a614f396b3c6 100644 --- a/hibernate-core/src/main/java/org/hibernate/cache/spi/support/DomainDataRegionTemplate.java +++ b/hibernate-core/src/main/java/org/hibernate/cache/spi/support/DomainDataRegionTemplate.java @@ -15,7 +15,6 @@ import org.hibernate.cache.spi.access.CollectionDataAccess; import org.hibernate.cache.spi.access.EntityDataAccess; import org.hibernate.cache.spi.access.NaturalIdDataAccess; -import org.hibernate.metamodel.model.domain.NavigableRole; import static org.hibernate.cache.spi.SecondLevelCacheLogger.L2CACHE_LOGGER; @@ -64,8 +63,8 @@ public DomainDataStorageAccess getCacheStorageAccess() { @Override public EntityDataAccess generateEntityAccess(EntityDataCachingConfig entityAccessConfig) { - final NavigableRole namedEntityRole = entityAccessConfig.getNavigableRole(); - final AccessType accessType = entityAccessConfig.getAccessType(); + final var namedEntityRole = entityAccessConfig.getNavigableRole(); + final var accessType = entityAccessConfig.getAccessType(); L2CACHE_LOGGER.tracef( "Generating entity cache access [%s] : %s", accessType.getExternalName(), namedEntityRole ); @@ -110,13 +109,14 @@ protected EntityDataAccess generateTransactionalEntityDataAccess(EntityDataCachi } private UnsupportedOperationException generateTransactionalNotSupportedException() { - return new UnsupportedOperationException( "Cache provider [" + getRegionFactory() + "] does not support `" + AccessType.TRANSACTIONAL.getExternalName() + "` access" ); + return new UnsupportedOperationException( "Cache provider [" + getRegionFactory() + "] does not support `" + + AccessType.TRANSACTIONAL.getExternalName() + "` access" ); } @Override public NaturalIdDataAccess generateNaturalIdAccess(NaturalIdDataCachingConfig accessConfig) { - final NavigableRole namedEntityRole = accessConfig.getNavigableRole(); - final AccessType accessType = accessConfig.getAccessType(); + final var namedEntityRole = accessConfig.getNavigableRole(); + final var accessType = accessConfig.getAccessType(); L2CACHE_LOGGER.tracef( "Generating entity natural-id access [%s] : %s", accessType.getExternalName(), namedEntityRole ); @@ -162,7 +162,7 @@ protected NaturalIdDataAccess generateTransactionalNaturalIdDataAccess(NaturalId @Override public CollectionDataAccess generateCollectionAccess(CollectionDataCachingConfig accessConfig) { - final NavigableRole namedCollectionRole = accessConfig.getNavigableRole(); + final var namedCollectionRole = accessConfig.getNavigableRole(); if ( L2CACHE_LOGGER.isTraceEnabled() ) { L2CACHE_LOGGER.trace( "Generating collection cache access: " + namedCollectionRole ); diff --git a/hibernate-core/src/main/java/org/hibernate/cache/spi/support/EntityNonStrictReadWriteAccess.java b/hibernate-core/src/main/java/org/hibernate/cache/spi/support/EntityNonStrictReadWriteAccess.java index cd6895265636..518041494fda 100644 --- a/hibernate-core/src/main/java/org/hibernate/cache/spi/support/EntityNonStrictReadWriteAccess.java +++ b/hibernate-core/src/main/java/org/hibernate/cache/spi/support/EntityNonStrictReadWriteAccess.java @@ -76,9 +76,4 @@ public boolean afterUpdate( public void unlockItem(SharedSessionContractImplementor session, Object key, SoftLock lock) throws CacheException { getStorageAccess().removeFromCache( key, session ); } - - @Override - public void remove(SharedSessionContractImplementor session, Object key) { - getStorageAccess().removeFromCache( key, session ); - } } diff --git a/hibernate-core/src/main/java/org/hibernate/cache/spi/support/EntityReadWriteAccess.java b/hibernate-core/src/main/java/org/hibernate/cache/spi/support/EntityReadWriteAccess.java index 5a74c50970d0..a1d36dee473b 100644 --- a/hibernate-core/src/main/java/org/hibernate/cache/spi/support/EntityReadWriteAccess.java +++ b/hibernate-core/src/main/java/org/hibernate/cache/spi/support/EntityReadWriteAccess.java @@ -24,7 +24,7 @@ */ public class EntityReadWriteAccess extends AbstractReadWriteAccess implements EntityDataAccess { private final CacheKeysFactory keysFactory; - private final Comparator versionComparator; + private final Comparator versionComparator; public EntityReadWriteAccess( DomainDataRegion domainDataRegion, @@ -33,9 +33,12 @@ public EntityReadWriteAccess( EntityDataCachingConfig entityAccessConfig) { super( domainDataRegion, storageAccess ); this.keysFactory = keysFactory; - this.versionComparator = entityAccessConfig.getVersionComparatorAccess() == null - ? null - : entityAccessConfig.getVersionComparatorAccess().get(); + final var versionComparatorAccess = + entityAccessConfig.getVersionComparatorAccess(); + this.versionComparator = + versionComparatorAccess == null + ? null + : versionComparatorAccess.get(); } @Override @@ -49,7 +52,7 @@ protected AccessedDataClassification getAccessedDataClassification() { } @Override - protected Comparator getVersionComparator() { + protected Comparator getVersionComparator() { return versionComparator; } @@ -67,6 +70,10 @@ public Object getCacheKeyId(Object cacheKey) { return keysFactory.getEntityId( cacheKey ); } + private void put(SharedSessionContractImplementor session, Object key, Object value, Object version) { + getStorageAccess().putIntoCache( key, new Item( value, version, nextTimestamp() ), session ); + } + @Override public boolean insert( SharedSessionContractImplementor session, @@ -80,13 +87,9 @@ public boolean insert( public boolean afterInsert(SharedSessionContractImplementor session, Object key, Object value, Object version) { try { writeLock().lock(); - Lockable item = (Lockable) getStorageAccess().getFromCache( key, session ); + final var item = (Lockable) getStorageAccess().getFromCache( key, session ); if ( item == null ) { - getStorageAccess().putIntoCache( - key, - new Item( value, version, getRegion().getRegionFactory().nextTimestamp() ), - session - ); + put( session, key, value, version ); return true; } else { @@ -121,22 +124,18 @@ public boolean afterUpdate( Lockable item = (Lockable) getStorageAccess().getFromCache( key, session ); if ( item != null && item.isUnlockable( lock ) ) { - SoftLockImpl lockItem = (SoftLockImpl) item; + final var lockItem = (SoftLockImpl) item; if ( lockItem.wasLockedConcurrently() ) { decrementLock( session, key, lockItem ); return false; } else { - getStorageAccess().putIntoCache( - key, - new Item( value, currentVersion, getRegion().getRegionFactory().nextTimestamp() ), - session - ); + put( session, key, value, currentVersion ); return true; } } else { - handleLockExpiry(session, key, item ); + handleLockExpiry( session, key ); return false; } } diff --git a/hibernate-core/src/main/java/org/hibernate/cache/spi/support/NaturalIdNonStrictReadWriteAccess.java b/hibernate-core/src/main/java/org/hibernate/cache/spi/support/NaturalIdNonStrictReadWriteAccess.java index f35bdb2b5ef9..4c040ae7f8cf 100644 --- a/hibernate-core/src/main/java/org/hibernate/cache/spi/support/NaturalIdNonStrictReadWriteAccess.java +++ b/hibernate-core/src/main/java/org/hibernate/cache/spi/support/NaturalIdNonStrictReadWriteAccess.java @@ -36,21 +36,11 @@ public void unlockItem(SharedSessionContractImplementor session, Object key, Sof getStorageAccess().removeFromCache( key, session ); } - @Override - public void remove(SharedSessionContractImplementor session, Object key) { - getStorageAccess().removeFromCache( key, session ); - } - @Override public boolean insert(SharedSessionContractImplementor session, Object key, Object value) { return false; } - @Override - public boolean afterInsert(SharedSessionContractImplementor session, Object key, Object value) { - return false; - } - @Override public boolean update(SharedSessionContractImplementor session, Object key, Object value) { getStorageAccess().removeFromCache( key, session ); diff --git a/hibernate-core/src/main/java/org/hibernate/cache/spi/support/NaturalIdReadWriteAccess.java b/hibernate-core/src/main/java/org/hibernate/cache/spi/support/NaturalIdReadWriteAccess.java index b419fdde6d23..7856d162b71b 100644 --- a/hibernate-core/src/main/java/org/hibernate/cache/spi/support/NaturalIdReadWriteAccess.java +++ b/hibernate-core/src/main/java/org/hibernate/cache/spi/support/NaturalIdReadWriteAccess.java @@ -44,8 +44,8 @@ public AccessType getAccessType() { } @Override - protected Comparator getVersionComparator() { - // natural-id has no comparator + protected Comparator getVersionComparator() { + // natural id has no comparator return null; } @@ -62,6 +62,10 @@ public Object getNaturalIdValues(Object cacheKey) { return keysFactory.getNaturalIdValues( cacheKey ); } + private void put(SharedSessionContractImplementor session, Object key, Object value) { + getStorageAccess().putIntoCache( key, new Item( value, null, nextTimestamp() ), session ); + } + @Override public boolean insert(SharedSessionContractImplementor session, Object key, Object value) { return false; @@ -71,13 +75,9 @@ public boolean insert(SharedSessionContractImplementor session, Object key, Obje public boolean afterInsert(SharedSessionContractImplementor session, Object key, Object value) { try { writeLock().lock(); - Lockable item = (Lockable) getStorageAccess().getFromCache( key, session ); + final var item = (Lockable) getStorageAccess().getFromCache( key, session ); if ( item == null ) { - getStorageAccess().putIntoCache( - key, - new Item( value, null, getRegion().getRegionFactory().nextTimestamp() ), - session - ); + put( session, key, value ); return true; } else { @@ -98,25 +98,20 @@ public boolean update(SharedSessionContractImplementor session, Object key, Obje public boolean afterUpdate(SharedSessionContractImplementor session, Object key, Object value, SoftLock lock) { try { writeLock().lock(); - Lockable item = (Lockable) getStorageAccess().getFromCache( key, session ); - + final var item = (Lockable) getStorageAccess().getFromCache( key, session ); if ( item != null && item.isUnlockable( lock ) ) { - SoftLockImpl lockItem = (SoftLockImpl) item; + final var lockItem = (SoftLockImpl) item; if ( lockItem.wasLockedConcurrently() ) { decrementLock( session, key, lockItem ); return false; } else { - getStorageAccess().putIntoCache( - key, - new Item( value, null, getRegion().getRegionFactory().nextTimestamp() ), - session - ); + put( session, key, value ); return true; } } else { - handleLockExpiry( session, key, item ); + handleLockExpiry( session, key ); return false; } } diff --git a/hibernate-core/src/main/java/org/hibernate/cache/spi/support/RegionNameQualifier.java b/hibernate-core/src/main/java/org/hibernate/cache/spi/support/RegionNameQualifier.java index b6cf9145a662..5496b0089ee2 100644 --- a/hibernate-core/src/main/java/org/hibernate/cache/spi/support/RegionNameQualifier.java +++ b/hibernate-core/src/main/java/org/hibernate/cache/spi/support/RegionNameQualifier.java @@ -17,22 +17,13 @@ public class RegionNameQualifier { public String qualify(String regionName, SessionFactoryOptions options) { final String prefix = options.getCacheRegionPrefix(); - if ( prefix == null ) { - return regionName; - } - - return qualify( prefix, regionName ); + return prefix == null ? regionName : qualify( prefix, regionName ); } public String qualify(String prefix, String regionName) { - if ( regionName.startsWith( prefix + '.' ) ) { - return regionName; - } - - return prefix + '.' + regionName; + return regionName.startsWith( prefix + '.' ) ? regionName : prefix + '.' + regionName; } - public boolean isQualified(String regionName, SessionFactoryOptions options) { return isQualified( options.getCacheRegionPrefix(), regionName ); } diff --git a/hibernate-core/src/main/java/org/hibernate/cache/spi/support/SimpleTimestamper.java b/hibernate-core/src/main/java/org/hibernate/cache/spi/support/SimpleTimestamper.java index a84c7ac33344..cb1ef04b154e 100644 --- a/hibernate-core/src/main/java/org/hibernate/cache/spi/support/SimpleTimestamper.java +++ b/hibernate-core/src/main/java/org/hibernate/cache/spi/support/SimpleTimestamper.java @@ -26,7 +26,6 @@ public static long next() { while ( true ) { long base = System.currentTimeMillis() << BIN_DIGITS; long maxValue = base + ONE_MS - 1; - for ( long current = VALUE.get(), update = Math.max( base, current + 1 ); update < maxValue; current = VALUE.get(), update = Math.max( base, current + 1 ) ) { if ( VALUE.compareAndSet( current, update ) ) { diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/service/ServiceContributorTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/service/ServiceContributorTest.java index d21cd348728a..93794e68c6e4 100644 --- a/hibernate-core/src/test/java/org/hibernate/orm/test/service/ServiceContributorTest.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/service/ServiceContributorTest.java @@ -27,13 +27,13 @@ public class ServiceContributorTest extends BaseUnitTestCase { @Test public void overrideCachingInitiator() { - StandardServiceRegistryBuilder ssrb = ServiceRegistryUtil.serviceRegistryBuilder(); + var ssrb = ServiceRegistryUtil.serviceRegistryBuilder(); ssrb.clearSettings(); - final MyRegionFactoryInitiator initiator = new MyRegionFactoryInitiator(); + final var initiator = new MyRegionFactoryInitiator(); ssrb.addInitiator( initiator ); - final ServiceRegistryImplementor registry = (ServiceRegistryImplementor) ssrb.build(); + final var registry = (ServiceRegistryImplementor) ssrb.build(); try { final RegionFactory regionFactory = registry.getService( RegionFactory.class ); assertTrue( initiator.called ); @@ -45,13 +45,13 @@ public void overrideCachingInitiator() { } @Test public void overrideCachingInitiatorExplicitSet() { - StandardServiceRegistryBuilder ssrb = ServiceRegistryUtil.serviceRegistryBuilder(); + var ssrb = ServiceRegistryUtil.serviceRegistryBuilder(); - final MyRegionFactoryInitiator initiator = new MyRegionFactoryInitiator(); + final var initiator = new MyRegionFactoryInitiator(); ssrb.addInitiator( initiator ); ssrb.applySetting( AvailableSettings.CACHE_REGION_FACTORY, new MyRegionFactory() ); - final ServiceRegistryImplementor registry = (ServiceRegistryImplementor) ssrb.build(); + final var registry = (ServiceRegistryImplementor) ssrb.build(); try { registry.getService( RegionFactory.class ); assertFalse( initiator.called ); @@ -61,12 +61,12 @@ public void overrideCachingInitiatorExplicitSet() { } } - class MyRegionFactoryInitiator extends RegionFactoryInitiator { + static class MyRegionFactoryInitiator extends RegionFactoryInitiator { private boolean called = false; @Override protected RegionFactory getFallback( - Map configurationValues, + Map configurationValues, ServiceRegistryImplementor registry) { called = true; return new MyRegionFactory(); @@ -81,7 +81,7 @@ protected RegionFactory getFallback( // } } - class MyRegionFactory extends CachingRegionFactory { + static class MyRegionFactory extends CachingRegionFactory { } }