diff --git a/hibernate-core/src/main/java/org/hibernate/boot/internal/MetadataBuilderImpl.java b/hibernate-core/src/main/java/org/hibernate/boot/internal/MetadataBuilderImpl.java index aad3ef4fed..c5dd6737d7 100644 --- a/hibernate-core/src/main/java/org/hibernate/boot/internal/MetadataBuilderImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/boot/internal/MetadataBuilderImpl.java @@ -7,7 +7,6 @@ package org.hibernate.boot.internal; import java.util.ArrayList; import java.util.List; import java.util.Locale; -import java.util.concurrent.Callable; import org.hibernate.AnnotationException; import org.hibernate.HibernateException; @@ -72,8 +71,6 @@ import org.hibernate.engine.jdbc.spi.JdbcServices; import org.hibernate.internal.CoreLogging; import org.hibernate.internal.CoreMessageLogger; import org.hibernate.internal.log.DeprecationLogger; -import org.hibernate.internal.util.NullnessHelper; -import org.hibernate.internal.util.collections.CollectionHelper; import org.hibernate.metamodel.CollectionClassification; import org.hibernate.query.sqm.function.SqmFunctionDescriptor; import org.hibernate.query.sqm.function.SqmFunctionRegistry; @@ -95,7 +92,9 @@ import static org.hibernate.cfg.AvailableSettings.JPA_COMPLIANCE; import static org.hibernate.cfg.AvailableSettings.WRAPPER_ARRAY_HANDLING; import static org.hibernate.cfg.MappingSettings.XML_FORMAT_MAPPER_LEGACY_FORMAT; import static org.hibernate.engine.config.spi.StandardConverters.BOOLEAN; +import static org.hibernate.internal.util.NullnessHelper.coalesceSuppliedValues; import static org.hibernate.internal.util.StringHelper.nullIfEmpty; +import static org.hibernate.internal.util.collections.CollectionHelper.isNotEmpty; /** * @author Steve Ebersole @@ -115,16 +114,15 @@ public class MetadataBuilderImpl implements MetadataBuilderImplementor, TypeCont if ( serviceRegistry == null ) { throw new HibernateException( "ServiceRegistry passed to MetadataBuilder cannot be null" ); } - - if ( serviceRegistry instanceof StandardServiceRegistry ) { - return (StandardServiceRegistry) serviceRegistry; + else if ( serviceRegistry instanceof StandardServiceRegistry standardServiceRegistry ) { + return standardServiceRegistry; } - else if ( serviceRegistry instanceof BootstrapServiceRegistry ) { + else if ( serviceRegistry instanceof BootstrapServiceRegistry bootstrapServiceRegistry ) { log.debug( "ServiceRegistry passed to MetadataBuilder was a BootstrapServiceRegistry; this likely won't end well " + "if attempt is made to build SessionFactory" ); - return new StandardServiceRegistryBuilder( (BootstrapServiceRegistry) serviceRegistry ).build(); + return new StandardServiceRegistryBuilder( bootstrapServiceRegistry ).build(); } else { throw new HibernateException( @@ -443,8 +441,9 @@ public class MetadataBuilderImpl implements MetadataBuilderImplementor, TypeCont final MetadataImplementor bootModel = MetadataBuildingProcess.build( sources, bootstrapContext, options ); - if ( CollectionHelper.isNotEmpty( sources.getHbmXmlBindings() ) ) { - final ConfigurationService configurationService = bootstrapContext.getServiceRegistry().getService( ConfigurationService.class ); + if ( isNotEmpty( sources.getHbmXmlBindings() ) ) { + final ConfigurationService configurationService = + bootstrapContext.getServiceRegistry().getService( ConfigurationService.class ); final boolean transformHbm = configurationService != null && configurationService.getSetting( MappingSettings.TRANSFORM_HBM_XML, BOOLEAN,false ); @@ -664,7 +663,7 @@ public class MetadataBuilderImpl implements MetadataBuilderImplementor, TypeCont mappingDefaults = new MappingDefaultsImpl( serviceRegistry ); defaultTimezoneStorage = resolveTimeZoneStorageStrategy( configService ); - wrapperArrayHandling = resolveWrapperArrayHandling( configService, serviceRegistry ); + wrapperArrayHandling = resolveWrapperArrayHandling( configService ); multiTenancyEnabled = JdbcEnvironmentImpl.isMultiTenancyEnabled( serviceRegistry ); xmlMappingEnabled = configService.getSetting( @@ -750,19 +749,14 @@ public class MetadataBuilderImpl implements MetadataBuilderImplementor, TypeCont null ) ); - implicitNamingStrategy = strategySelector.resolveDefaultableStrategy( + implicitNamingStrategy = strategySelector.resolveDefaultableStrategy( ImplicitNamingStrategy.class, configService.getSettings().get( AvailableSettings.IMPLICIT_NAMING_STRATEGY ), - new Callable<>() { - @Override - public ImplicitNamingStrategy call() { - return strategySelector.resolveDefaultableStrategy( - ImplicitNamingStrategy.class, - "default", - ImplicitNamingStrategyJpaCompliantImpl.INSTANCE - ); - } - } + () -> strategySelector.resolveDefaultableStrategy( + ImplicitNamingStrategy.class, + "default", + ImplicitNamingStrategyJpaCompliantImpl.INSTANCE + ) ); physicalNamingStrategy = strategySelector.resolveDefaultableStrategy( @@ -771,19 +765,14 @@ public class MetadataBuilderImpl implements MetadataBuilderImplementor, TypeCont PhysicalNamingStrategyStandardImpl.INSTANCE ); - columnOrderingStrategy = strategySelector.resolveDefaultableStrategy( + columnOrderingStrategy = strategySelector.resolveDefaultableStrategy( ColumnOrderingStrategy.class, configService.getSettings().get( AvailableSettings.COLUMN_ORDERING_STRATEGY ), - new Callable<>() { - @Override - public ColumnOrderingStrategy call() { - return strategySelector.resolveDefaultableStrategy( - ColumnOrderingStrategy.class, - "default", - ColumnOrderingStrategyStandard.INSTANCE - ); - } - } + () -> strategySelector.resolveDefaultableStrategy( + ColumnOrderingStrategy.class, + "default", + ColumnOrderingStrategyStandard.INSTANCE + ) ); useNationalizedCharacterData = configService.getSetting( @@ -820,12 +809,14 @@ public class MetadataBuilderImpl implements MetadataBuilderImplementor, TypeCont return toTimeZoneStorageStrategy( getTimeZoneSupport() ); } + private Dialect getDialect() { + return serviceRegistry.requireService( JdbcServices.class ).getDialect(); + } + @Override public TimeZoneSupport getTimeZoneSupport() { try { - return serviceRegistry.requireService( JdbcServices.class ) - .getDialect() - .getTimeZoneSupport(); + return getDialect().getTimeZoneSupport(); } catch ( ServiceException se ) { return TimeZoneSupport.NONE; @@ -844,27 +835,25 @@ public class MetadataBuilderImpl implements MetadataBuilderImplementor, TypeCont case NORMALIZE -> TimeZoneStorageStrategy.NORMALIZE; case NORMALIZE_UTC -> TimeZoneStorageStrategy.NORMALIZE_UTC; case AUTO -> switch (timeZoneSupport) { - case NATIVE -> - // if the db has native support for timezones, we use that, not a column - TimeZoneStorageStrategy.NATIVE; - case NORMALIZE, NONE -> - // otherwise we use a separate column - TimeZoneStorageStrategy.COLUMN; + // if the db has native support for timezones, we use that, not a column + case NATIVE -> TimeZoneStorageStrategy.NATIVE; + // otherwise we use a separate column + case NORMALIZE, NONE -> TimeZoneStorageStrategy.COLUMN; }; case DEFAULT -> switch (timeZoneSupport) { - case NATIVE -> - // if the db has native support for timezones, we use that, and don't normalize - TimeZoneStorageStrategy.NATIVE; - case NORMALIZE, NONE -> - // otherwise we normalize things to UTC - TimeZoneStorageStrategy.NORMALIZE_UTC; + // if the db has native support for timezones, we use that, and don't normalize + case NATIVE -> TimeZoneStorageStrategy.NATIVE; + // otherwise we normalize things to UTC + case NORMALIZE, NONE -> TimeZoneStorageStrategy.NORMALIZE_UTC; }; }; } @Override public WrapperArrayHandling getWrapperArrayHandling() { - return wrapperArrayHandling; + return wrapperArrayHandling == WrapperArrayHandling.PICK + ? pickWrapperArrayHandling( getDialect() ) + : wrapperArrayHandling; } @Override @@ -979,9 +968,7 @@ public class MetadataBuilderImpl implements MetadataBuilderImplementor, TypeCont } if ( mappingDefaults.getImplicitSchemaName() == null ) { - mappingDefaults.implicitSchemaName = nullIfEmpty( - jpaOrmXmlPersistenceUnitDefaults.getDefaultSchemaName() - ); + mappingDefaults.implicitSchemaName = nullIfEmpty( jpaOrmXmlPersistenceUnitDefaults.getDefaultSchemaName() ); } } @@ -1015,29 +1002,25 @@ public class MetadataBuilderImpl implements MetadataBuilderImplementor, TypeCont } private static WrapperArrayHandling resolveWrapperArrayHandling( - ConfigurationService configService, - StandardServiceRegistry serviceRegistry) { - final WrapperArrayHandling setting = NullnessHelper.coalesceSuppliedValues( + ConfigurationService configService) { + return coalesceSuppliedValues( () -> configService.getSetting( WRAPPER_ARRAY_HANDLING, WrapperArrayHandling::interpretExternalSettingLeniently ), () -> resolveFallbackWrapperArrayHandling( configService ) ); + } - if ( setting == WrapperArrayHandling.PICK ) { - final Dialect dialect = serviceRegistry.requireService( JdbcServices.class ).getDialect(); - if ( dialect.supportsStandardArrays() - && ( dialect.getPreferredSqlTypeCodeForArray() == SqlTypes.ARRAY - || dialect.getPreferredSqlTypeCodeForArray() == SqlTypes.SQLXML ) ) { - return WrapperArrayHandling.ALLOW; - } - else { - return WrapperArrayHandling.LEGACY; - } + private static WrapperArrayHandling pickWrapperArrayHandling(Dialect dialect) { + if ( dialect.supportsStandardArrays() + && ( dialect.getPreferredSqlTypeCodeForArray() == SqlTypes.ARRAY + || dialect.getPreferredSqlTypeCodeForArray() == SqlTypes.SQLXML ) ) { + return WrapperArrayHandling.ALLOW; + } + else { + return WrapperArrayHandling.LEGACY; } - - return setting; } private static WrapperArrayHandling resolveFallbackWrapperArrayHandling( diff --git a/hibernate-core/src/main/java/org/hibernate/dialect/XmlHelper.java b/hibernate-core/src/main/java/org/hibernate/dialect/XmlHelper.java index 178932707e..1c924bf55b 100644 --- a/hibernate-core/src/main/java/org/hibernate/dialect/XmlHelper.java +++ b/hibernate-core/src/main/java/org/hibernate/dialect/XmlHelper.java @@ -1124,19 +1124,15 @@ public class XmlHelper { } //noinspection unchecked final JavaType javaType = (JavaType) pluralJavaType; - final LazySessionWrapperOptions lazySessionWrapperOptions = new LazySessionWrapperOptions( sessionFactory ); // Produce the XML string for a collection with a null element to find out the root and element tag names final String nullElementXml; - try { + try ( final LazySessionWrapperOptions lazySessionWrapperOptions = new LazySessionWrapperOptions( sessionFactory ) ) { nullElementXml = sessionFactory.getSessionFactoryOptions().getXmlFormatMapper().toString( javaType.fromString( "{null}" ), javaType, lazySessionWrapperOptions ); } - finally { - lazySessionWrapperOptions.cleanup(); - } // There must be an end tag for the root, so find that first final int rootCloseTagPosition = nullElementXml.lastIndexOf( '<' ); diff --git a/hibernate-core/src/main/java/org/hibernate/dialect/aggregate/OracleAggregateSupport.java b/hibernate-core/src/main/java/org/hibernate/dialect/aggregate/OracleAggregateSupport.java index 8394a4dad9..d498080d42 100644 --- a/hibernate-core/src/main/java/org/hibernate/dialect/aggregate/OracleAggregateSupport.java +++ b/hibernate-core/src/main/java/org/hibernate/dialect/aggregate/OracleAggregateSupport.java @@ -312,6 +312,7 @@ public class OracleAggregateSupport extends AggregateSupportImpl { return typeConfiguration.getSessionFactory().getWrapperOptions(); } catch (HibernateException e) { + // before we have a SessionFactory, no useful WrapperOptions to pass return null; } } @@ -549,16 +550,11 @@ public class OracleAggregateSupport extends AggregateSupportImpl { final String columnDefinition = aggregateColumn.getColumnDefinition(); if ( columnDefinition == null ) { assert aggregateColumn.getJdbcMapping().getJdbcType().getDefaultSqlTypeCode() == JSON; - switch ( jsonSupport ) { - case OSON: - return "json"; - case MERGEPATCH: - case QUERY_AND_PATH: - case QUERY: - return "blob"; - case NONE: - return "clob"; - } + return switch ( jsonSupport ) { + case OSON -> "json"; + case MERGEPATCH, QUERY_AND_PATH, QUERY -> "blob"; + case NONE -> "clob"; + }; } return columnDefinition; } diff --git a/hibernate-core/src/main/java/org/hibernate/dialect/function/NumberSeriesGenerateSeriesFunction.java b/hibernate-core/src/main/java/org/hibernate/dialect/function/NumberSeriesGenerateSeriesFunction.java index f0f334f355..1b89d24bce 100644 --- a/hibernate-core/src/main/java/org/hibernate/dialect/function/NumberSeriesGenerateSeriesFunction.java +++ b/hibernate-core/src/main/java/org/hibernate/dialect/function/NumberSeriesGenerateSeriesFunction.java @@ -485,8 +485,7 @@ public abstract class NumberSeriesGenerateSeriesFunction extends GenerateSeriesF private String getExpression(Expression expression, String tableIdentifierVariable, String syntheticColumnName, SqmToSqlAstConverter walker) { if ( expression instanceof Literal literal ) { final SessionFactoryImplementor sessionFactory = walker.getCreationContext().getSessionFactory(); - final LazySessionWrapperOptions wrapperOptions = new LazySessionWrapperOptions( sessionFactory ); - try { + try ( final LazySessionWrapperOptions wrapperOptions = new LazySessionWrapperOptions( sessionFactory ) ) { //noinspection unchecked return literal.getJdbcMapping().getJdbcLiteralFormatter().toJdbcLiteral( literal.getLiteralValue(), @@ -494,9 +493,6 @@ public abstract class NumberSeriesGenerateSeriesFunction extends GenerateSeriesF wrapperOptions ); } - finally { - wrapperOptions.cleanup(); - } } else if ( expression instanceof ColumnReference columnReference ) { return columnReference.getExpressionText(); diff --git a/hibernate-core/src/main/java/org/hibernate/engine/spi/AbstractDelegatingWrapperOptions.java b/hibernate-core/src/main/java/org/hibernate/engine/spi/AbstractDelegatingWrapperOptions.java index 6f03420654..bb1101c2d3 100644 --- a/hibernate-core/src/main/java/org/hibernate/engine/spi/AbstractDelegatingWrapperOptions.java +++ b/hibernate-core/src/main/java/org/hibernate/engine/spi/AbstractDelegatingWrapperOptions.java @@ -12,7 +12,11 @@ import org.hibernate.type.descriptor.WrapperOptions; /** * @author Christian Beikov * @author Andrea Boriero + * + * @deprecated This isn't bringing any value, since {@link SessionImplementor} + * already extends {@link WrapperOptions}. */ +@Deprecated(since = "7", forRemoval = true) public abstract class AbstractDelegatingWrapperOptions implements WrapperOptions { /** diff --git a/hibernate-core/src/main/java/org/hibernate/engine/spi/LazySessionWrapperOptions.java b/hibernate-core/src/main/java/org/hibernate/engine/spi/LazySessionWrapperOptions.java index c358d96af6..ace47cd84b 100644 --- a/hibernate-core/src/main/java/org/hibernate/engine/spi/LazySessionWrapperOptions.java +++ b/hibernate-core/src/main/java/org/hibernate/engine/spi/LazySessionWrapperOptions.java @@ -7,23 +7,37 @@ package org.hibernate.engine.spi; import java.util.TimeZone; import org.hibernate.Internal; +import org.hibernate.dialect.Dialect; +import org.hibernate.engine.jdbc.LobCreator; +import org.hibernate.internal.FastSessionServices; import org.hibernate.type.descriptor.WrapperOptions; import org.checkerframework.checker.nullness.qual.Nullable; /** - * A lazy session implementation that is needed for rendering literals. - * Usually, only the {@link WrapperOptions} interface is needed, - * but for creating LOBs, it might be to have a full-blown session. + * An implementation of {@link WrapperOptions} used for rendering SQL literals, + * which is backed by the {@link SessionFactoryImplementor}, and which + * {@linkplain SessionFactoryImplementor#openTemporarySession lazily creates a + * temporary session if needed.} The temporary session will only be created when + * dealing with LOBs. + *

+ * This object is {@link AutoCloseable}, and must be explicitly cleaned + * up by its creator. + * + * @apiNote This thing is nasty, and we should find a better way to solve the problem. + * Whenever possible, just use {@link SessionFactoryImplementor#getWrapperOptions()} + * instead. */ @Internal -public class LazySessionWrapperOptions extends AbstractDelegatingWrapperOptions { +public class LazySessionWrapperOptions implements WrapperOptions, AutoCloseable { private final SessionFactoryImplementor sessionFactory; + private final FastSessionServices fastSessionServices; private @Nullable SessionImplementor session; public LazySessionWrapperOptions(SessionFactoryImplementor sessionFactory) { this.sessionFactory = sessionFactory; + fastSessionServices = sessionFactory.getFastSessionServices(); } public void cleanup() { @@ -34,16 +48,14 @@ public class LazySessionWrapperOptions extends AbstractDelegatingWrapperOptions } @Override - protected SessionImplementor delegate() { - if ( session == null ) { - session = sessionFactory.openTemporarySession(); - } - return session; + public void close() { + cleanup(); } @Override public SharedSessionContractImplementor getSession() { - return delegate(); + session = sessionFactory.openTemporarySession(); + return session; } @Override @@ -53,16 +65,26 @@ public class LazySessionWrapperOptions extends AbstractDelegatingWrapperOptions @Override public boolean useStreamForLobBinding() { - return sessionFactory.getFastSessionServices().useStreamForLobBinding(); + return fastSessionServices.useStreamForLobBinding; } @Override public int getPreferredSqlTypeCodeForBoolean() { - return sessionFactory.getFastSessionServices().getPreferredSqlTypeCodeForBoolean(); + return fastSessionServices.preferredSqlTypeCodeForBoolean; } @Override public TimeZone getJdbcTimeZone() { - return sessionFactory.getSessionFactoryOptions().getJdbcTimeZone(); + return fastSessionServices.jdbcTimeZone; + } + + @Override + public Dialect getDialect() { + return fastSessionServices.dialect; + } + + @Override + public LobCreator getLobCreator() { + return fastSessionServices.jdbcServices.getLobCreator( getSession() ); } } diff --git a/hibernate-core/src/main/java/org/hibernate/engine/spi/SessionFactoryImplementor.java b/hibernate-core/src/main/java/org/hibernate/engine/spi/SessionFactoryImplementor.java index 74b8a0e66f..bb83e521d1 100644 --- a/hibernate-core/src/main/java/org/hibernate/engine/spi/SessionFactoryImplementor.java +++ b/hibernate-core/src/main/java/org/hibernate/engine/spi/SessionFactoryImplementor.java @@ -7,7 +7,6 @@ package org.hibernate.engine.spi; import java.util.Collection; import org.hibernate.CustomEntityDirtinessStrategy; -import org.hibernate.HibernateException; import org.hibernate.SessionFactory; import org.hibernate.SessionFactoryObserver; import org.hibernate.boot.model.relational.SqlStringGenerationContext; @@ -94,7 +93,7 @@ public interface SessionFactoryImplementor /** * Get a non-transactional "current" session (used by hibernate-envers) */ - SessionImplementor openTemporarySession() throws HibernateException; + SessionImplementor openTemporarySession(); @Override CacheImplementor getCache(); diff --git a/hibernate-core/src/main/java/org/hibernate/internal/AbstractSharedSessionContract.java b/hibernate-core/src/main/java/org/hibernate/internal/AbstractSharedSessionContract.java index bab9f88185..634b5a5b50 100644 --- a/hibernate-core/src/main/java/org/hibernate/internal/AbstractSharedSessionContract.java +++ b/hibernate-core/src/main/java/org/hibernate/internal/AbstractSharedSessionContract.java @@ -34,6 +34,7 @@ import org.hibernate.UnknownEntityTypeException; import org.hibernate.binder.internal.TenantIdBinder; import org.hibernate.cache.spi.CacheTransactionSynchronization; import org.hibernate.context.spi.CurrentTenantIdentifierResolver; +import org.hibernate.dialect.Dialect; import org.hibernate.engine.internal.SessionEventListenerManagerImpl; import org.hibernate.engine.jdbc.LobCreator; import org.hibernate.engine.jdbc.connections.spi.JdbcConnectionAccess; @@ -702,6 +703,11 @@ public abstract class AbstractSharedSessionContract implements SharedSessionCont return new EntityKey( id, persister ); } + @Override + public SessionFactoryImplementor getSessionFactory() { + return factory; + } + @Override public boolean useStreamForLobBinding() { return fastSessionServices.useStreamForLobBinding; @@ -714,7 +720,12 @@ public abstract class AbstractSharedSessionContract implements SharedSessionCont @Override public LobCreator getLobCreator() { - return getFactory().getFastSessionServices().jdbcServices.getLobCreator( this ); + return fastSessionServices.jdbcServices.getLobCreator( this ); + } + + @Override + public Dialect getDialect() { + return fastSessionServices.dialect; } @Override @@ -1417,7 +1428,7 @@ public abstract class AbstractSharedSessionContract implements SharedSessionCont @Override public EventManager getEventManager() { - return fastSessionServices.getEventManager(); + return fastSessionServices.eventManager; } @Override diff --git a/hibernate-core/src/main/java/org/hibernate/internal/FastSessionServices.java b/hibernate-core/src/main/java/org/hibernate/internal/FastSessionServices.java index 33aea1b209..d1715e62c1 100644 --- a/hibernate-core/src/main/java/org/hibernate/internal/FastSessionServices.java +++ b/hibernate-core/src/main/java/org/hibernate/internal/FastSessionServices.java @@ -8,59 +8,24 @@ import java.util.Collection; import java.util.HashMap; import java.util.Map; import java.util.Objects; +import java.util.TimeZone; import org.hibernate.CacheMode; import org.hibernate.FlushMode; import org.hibernate.HibernateException; import org.hibernate.LockOptions; -import org.hibernate.TimeZoneStorageStrategy; import org.hibernate.boot.registry.classloading.spi.ClassLoaderService; import org.hibernate.boot.spi.SessionFactoryOptions; import org.hibernate.dialect.Dialect; import org.hibernate.engine.jdbc.batch.spi.BatchBuilder; import org.hibernate.engine.jdbc.connections.spi.ConnectionProvider; import org.hibernate.engine.jdbc.connections.spi.MultiTenantConnectionProvider; -import org.hibernate.engine.jdbc.mutation.spi.MutationExecutorService; import org.hibernate.engine.jdbc.spi.JdbcServices; import org.hibernate.engine.spi.SessionFactoryImplementor; import org.hibernate.event.internal.EmptyEventManager; import org.hibernate.event.service.spi.EventListenerGroup; import org.hibernate.event.service.spi.EventListenerRegistry; -import org.hibernate.event.spi.AutoFlushEventListener; -import org.hibernate.event.spi.ClearEventListener; -import org.hibernate.event.spi.DeleteEventListener; -import org.hibernate.event.spi.DirtyCheckEventListener; -import org.hibernate.event.spi.EntityCopyObserverFactory; -import org.hibernate.event.spi.EventManager; -import org.hibernate.event.spi.EventType; -import org.hibernate.event.spi.EvictEventListener; -import org.hibernate.event.spi.FlushEntityEventListener; -import org.hibernate.event.spi.FlushEventListener; -import org.hibernate.event.spi.InitializeCollectionEventListener; -import org.hibernate.event.spi.LoadEventListener; -import org.hibernate.event.spi.LockEventListener; -import org.hibernate.event.spi.MergeEventListener; -import org.hibernate.event.spi.PersistEventListener; -import org.hibernate.event.spi.PostCollectionRecreateEventListener; -import org.hibernate.event.spi.PostCollectionRemoveEventListener; -import org.hibernate.event.spi.PostCollectionUpdateEventListener; -import org.hibernate.event.spi.PostDeleteEventListener; -import org.hibernate.event.spi.PostInsertEventListener; -import org.hibernate.event.spi.PostLoadEvent; -import org.hibernate.event.spi.PostLoadEventListener; -import org.hibernate.event.spi.PostUpdateEventListener; -import org.hibernate.event.spi.PostUpsertEventListener; -import org.hibernate.event.spi.PreCollectionRecreateEventListener; -import org.hibernate.event.spi.PreCollectionRemoveEventListener; -import org.hibernate.event.spi.PreCollectionUpdateEventListener; -import org.hibernate.event.spi.PreDeleteEventListener; -import org.hibernate.event.spi.PreInsertEventListener; -import org.hibernate.event.spi.PreLoadEventListener; -import org.hibernate.event.spi.PreUpdateEventListener; -import org.hibernate.event.spi.PreUpsertEventListener; -import org.hibernate.event.spi.RefreshEventListener; -import org.hibernate.event.spi.ReplicateEventListener; -import org.hibernate.event.spi.ResolveNaturalIdEventListener; +import org.hibernate.event.spi.*; import org.hibernate.jpa.HibernateHints; import org.hibernate.jpa.LegacySpecHints; import org.hibernate.jpa.SpecHints; @@ -152,17 +117,14 @@ public final class FastSessionServices { public final EventListenerGroup eventListenerGroup_REPLICATE; public final EventListenerGroup eventListenerGroup_RESOLVE_NATURAL_ID; - //Intentionally Package private: + // Fields used only from within this package final boolean disallowOutOfTransactionUpdateOperations; - final boolean useStreamForLobBinding; - final int preferredSqlTypeCodeForBoolean; - final TimeZoneStorageStrategy defaultTimeZoneStorageStrategy; final boolean requiresMultiTenantConnectionProvider; final ConnectionProvider connectionProvider; final MultiTenantConnectionProvider multiTenantConnectionProvider; final ClassLoaderService classLoaderService; final TransactionCoordinatorBuilder transactionCoordinatorBuilder; - public final JdbcServices jdbcServices; + final EventManager eventManager; final boolean isJtaTransactionAccessible; final CacheMode initialSessionCacheMode; final FlushMode initialSessionFlushMode; @@ -171,20 +133,23 @@ public final class FastSessionServices { final LockOptions defaultLockOptions; final int defaultJdbcBatchSize; - //Some fields are handy as public - still considered internal. + // Expose certain fields outside this package + // (but they are still considered internal) + public final Dialect dialect; + public final JdbcServices jdbcServices; + public final boolean useStreamForLobBinding; + public final int preferredSqlTypeCodeForBoolean; + public final TimeZone jdbcTimeZone; public final EntityCopyObserverFactory entityCopyObserverFactory; public final BatchBuilder batchBuilder; - public final Dialect dialect; public final ParameterMarkerStrategy parameterMarkerStrategy; - //Private fields: + // Private fields (probably don't really belong here) private final CacheStoreMode defaultCacheStoreMode; private final CacheRetrieveMode defaultCacheRetrieveMode; private final FormatMapper jsonFormatMapper; private final FormatMapper xmlFormatMapper; - private final MutationExecutorService mutationExecutorService; private final JdbcValuesMappingProducerProvider jdbcValuesMappingProducerProvider; - private final EventManager eventManager; FastSessionServices(SessionFactoryImplementor sessionFactory) { Objects.requireNonNull( sessionFactory ); @@ -235,11 +200,10 @@ public final class FastSessionServices { this.disallowOutOfTransactionUpdateOperations = !sessionFactoryOptions.isAllowOutOfTransactionUpdateOperations(); this.useStreamForLobBinding = dialect.useInputStreamToInsertBlob(); this.preferredSqlTypeCodeForBoolean = sessionFactoryOptions.getPreferredSqlTypeCodeForBoolean(); - this.defaultTimeZoneStorageStrategy = sessionFactoryOptions.getDefaultTimeZoneStorageStrategy(); this.defaultJdbcBatchSize = sessionFactoryOptions.getJdbcBatchSize(); + this.jdbcTimeZone = sessionFactoryOptions.getJdbcTimeZone(); this.requiresMultiTenantConnectionProvider = sessionFactory.getSessionFactoryOptions().isMultiTenancyEnabled(); this.parameterMarkerStrategy = serviceRegistry.getService( ParameterMarkerStrategy.class ); - this.mutationExecutorService = serviceRegistry.getService( MutationExecutorService.class ); //Some "hot" services: this.connectionProvider = requiresMultiTenantConnectionProvider @@ -254,7 +218,6 @@ public final class FastSessionServices { this.entityCopyObserverFactory = serviceRegistry.requireService( EntityCopyObserverFactory.class ); this.jdbcValuesMappingProducerProvider = serviceRegistry.getService( JdbcValuesMappingProducerProvider.class ); - this.isJtaTransactionAccessible = isTransactionAccessible( sessionFactory, transactionCoordinatorBuilder ); this.defaultSessionProperties = initializeDefaultSessionProperties( sessionFactory ); @@ -268,10 +231,9 @@ public final class FastSessionServices { this.jsonFormatMapper = sessionFactoryOptions.getJsonFormatMapper(); this.xmlFormatMapper = sessionFactoryOptions.getXmlFormatMapper(); this.batchBuilder = serviceRegistry.getService( BatchBuilder.class ); + final Collection eventManagers = classLoaderService.loadJavaServices( EventManager.class ); - this.eventManager = eventManagers.isEmpty() - ? new EmptyEventManager() - : eventManagers.iterator().next(); + this.eventManager = eventManagers.isEmpty() ? new EmptyEventManager() : eventManagers.iterator().next(); } private static FlushMode initializeDefaultFlushMode(Map defaultSessionProperties) { @@ -374,27 +336,10 @@ public final class FastSessionServices { return this.jdbcValuesMappingProducerProvider; } - public EventManager getEventManager() { - return eventManager; - } - - public boolean useStreamForLobBinding() { - return useStreamForLobBinding; - } - public void firePostLoadEvent(final PostLoadEvent postLoadEvent) { eventListenerGroup_POST_LOAD.fireEventOnEachListener( postLoadEvent, PostLoadEventListener::onPostLoad ); } - public int getPreferredSqlTypeCodeForBoolean() { - return preferredSqlTypeCodeForBoolean; - } - - @Deprecated(forRemoval = true) //This seems no longer used - cleanup? - public TimeZoneStorageStrategy getDefaultTimeZoneStorageStrategy() { - return defaultTimeZoneStorageStrategy; - } - public FormatMapper getJsonFormatMapper() { if ( jsonFormatMapper == null ) { throw new HibernateException( @@ -412,10 +357,4 @@ public final class FastSessionServices { } return xmlFormatMapper; } - - @Deprecated(forRemoval = true) //This seems no longer used - cleanup? - public MutationExecutorService getMutationExecutorService() { - return mutationExecutorService; - } - } diff --git a/hibernate-core/src/main/java/org/hibernate/persister/entity/SessionFactoryBasedWrapperOptions.java b/hibernate-core/src/main/java/org/hibernate/internal/SessionFactoryBasedWrapperOptions.java similarity index 58% rename from hibernate-core/src/main/java/org/hibernate/persister/entity/SessionFactoryBasedWrapperOptions.java rename to hibernate-core/src/main/java/org/hibernate/internal/SessionFactoryBasedWrapperOptions.java index 3de878c6d3..335c695b3e 100644 --- a/hibernate-core/src/main/java/org/hibernate/persister/entity/SessionFactoryBasedWrapperOptions.java +++ b/hibernate-core/src/main/java/org/hibernate/internal/SessionFactoryBasedWrapperOptions.java @@ -2,11 +2,11 @@ * SPDX-License-Identifier: LGPL-2.1-or-later * Copyright Red Hat Inc. and Hibernate Authors */ -package org.hibernate.persister.entity; +package org.hibernate.internal; import java.util.TimeZone; -import org.hibernate.Internal; +import org.hibernate.dialect.Dialect; import org.hibernate.engine.jdbc.LobCreator; import org.hibernate.engine.spi.SessionFactoryImplementor; import org.hibernate.engine.spi.SharedSessionContractImplementor; @@ -16,13 +16,14 @@ import org.hibernate.type.descriptor.WrapperOptions; * * @author Christian Beikov */ -@Internal -public class SessionFactoryBasedWrapperOptions implements WrapperOptions { +class SessionFactoryBasedWrapperOptions implements WrapperOptions { private final SessionFactoryImplementor factory; + private final FastSessionServices fastSessionServices; - public SessionFactoryBasedWrapperOptions(SessionFactoryImplementor factory) { + SessionFactoryBasedWrapperOptions(SessionFactoryImplementor factory) { this.factory = factory; + fastSessionServices = factory.getFastSessionServices(); } @Override @@ -37,21 +38,26 @@ public class SessionFactoryBasedWrapperOptions implements WrapperOptions { @Override public boolean useStreamForLobBinding() { - return factory.getFastSessionServices().useStreamForLobBinding(); + return fastSessionServices.useStreamForLobBinding; } @Override public int getPreferredSqlTypeCodeForBoolean() { - return factory.getFastSessionServices().getPreferredSqlTypeCodeForBoolean(); + return fastSessionServices.preferredSqlTypeCodeForBoolean; } @Override public LobCreator getLobCreator() { - return factory.getJdbcServices().getLobCreator( getSession() ); + return fastSessionServices.jdbcServices.getLobCreator( getSession() ); } @Override public TimeZone getJdbcTimeZone() { - return factory.getSessionFactoryOptions().getJdbcTimeZone(); + return fastSessionServices.jdbcTimeZone; + } + + @Override + public Dialect getDialect() { + return fastSessionServices.dialect; } } diff --git a/hibernate-core/src/main/java/org/hibernate/internal/SessionFactoryImpl.java b/hibernate-core/src/main/java/org/hibernate/internal/SessionFactoryImpl.java index d96db932bd..f4703b66f0 100644 --- a/hibernate-core/src/main/java/org/hibernate/internal/SessionFactoryImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/internal/SessionFactoryImpl.java @@ -83,7 +83,6 @@ import org.hibernate.metamodel.model.domain.spi.JpaMetamodelImplementor; import org.hibernate.metamodel.spi.MappingMetamodelImplementor; import org.hibernate.metamodel.spi.RuntimeMetamodelsImplementor; import org.hibernate.metamodel.spi.RuntimeModelCreationContext; -import org.hibernate.persister.entity.SessionFactoryBasedWrapperOptions; import org.hibernate.procedure.spi.ProcedureCallImplementor; import org.hibernate.proxy.EntityNotFoundDelegate; import org.hibernate.proxy.LazyInitializer; diff --git a/hibernate-core/src/main/java/org/hibernate/internal/SessionImpl.java b/hibernate-core/src/main/java/org/hibernate/internal/SessionImpl.java index e524285d34..5a820190a5 100644 --- a/hibernate-core/src/main/java/org/hibernate/internal/SessionImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/internal/SessionImpl.java @@ -1646,12 +1646,6 @@ public class SessionImpl return super.createStoredProcedureCall( procedureName, resultClasses ); } - @Override - public SessionFactoryImplementor getSessionFactory() { -// checkTransactionSynchStatus(); - return getFactory(); - } - @Override public QueryImplementor createQuery(CriteriaSelect selectQuery) { checkOpen(); diff --git a/hibernate-core/src/main/java/org/hibernate/type/descriptor/WrapperOptions.java b/hibernate-core/src/main/java/org/hibernate/type/descriptor/WrapperOptions.java index a18a3faf3c..82d6fc831f 100644 --- a/hibernate-core/src/main/java/org/hibernate/type/descriptor/WrapperOptions.java +++ b/hibernate-core/src/main/java/org/hibernate/type/descriptor/WrapperOptions.java @@ -47,7 +47,9 @@ public interface WrapperOptions { * * @see org.hibernate.dialect.Dialect#useInputStreamToInsertBlob() */ - boolean useStreamForLobBinding(); + default boolean useStreamForLobBinding() { + return getDialect().useInputStreamToInsertBlob(); + } /** * The JDBC {@link java.sql.Types type code} used to bind a null boolean value. @@ -55,7 +57,9 @@ public interface WrapperOptions { * @see org.hibernate.cfg.AvailableSettings#PREFERRED_BOOLEAN_JDBC_TYPE * @see org.hibernate.dialect.Dialect#getPreferredSqlTypeCodeForBoolean() */ - int getPreferredSqlTypeCodeForBoolean(); + default int getPreferredSqlTypeCodeForBoolean() { + return getSessionFactory().getSessionFactoryOptions().getPreferredSqlTypeCodeForBoolean(); + } /** * Obtain access to the {@link LobCreator}. @@ -65,7 +69,9 @@ public interface WrapperOptions { * @see org.hibernate.cfg.AvailableSettings#NON_CONTEXTUAL_LOB_CREATION * @see org.hibernate.dialect.Dialect#getDefaultNonContextualLobCreation() */ - LobCreator getLobCreator(); + default LobCreator getLobCreator() { + return getSession().getLobCreator(); + } /** * The JDBC {@link TimeZone} used when writing a value of type {@link java.sql.Time} @@ -90,5 +96,7 @@ public interface WrapperOptions { * * @see org.hibernate.cfg.AvailableSettings#JDBC_TIME_ZONE */ - TimeZone getJdbcTimeZone(); + default TimeZone getJdbcTimeZone() { + return getSessionFactory().getSessionFactoryOptions().getJdbcTimeZone(); + } } diff --git a/hibernate-core/src/main/java/org/hibernate/type/descriptor/jdbc/spi/BasicJdbcLiteralFormatter.java b/hibernate-core/src/main/java/org/hibernate/type/descriptor/jdbc/spi/BasicJdbcLiteralFormatter.java index 8d9b6004fb..390151e5b0 100644 --- a/hibernate-core/src/main/java/org/hibernate/type/descriptor/jdbc/spi/BasicJdbcLiteralFormatter.java +++ b/hibernate-core/src/main/java/org/hibernate/type/descriptor/jdbc/spi/BasicJdbcLiteralFormatter.java @@ -26,19 +26,17 @@ public abstract class BasicJdbcLiteralFormatter extends AbstractJdbcLiteralFo if ( unwrapType.isInstance( value ) ) { return (X) value; } - - if ( !getJavaType().isInstance( value ) ) { + else if ( !getJavaType().isInstance( value ) ) { final T coerce = getJavaType().coerce( value, wrapperOptions.getSession() ); if ( unwrapType.isInstance( coerce ) ) { return (X) coerce; } - return getJavaType().unwrap( - coerce, - unwrapType, - wrapperOptions - ); + else { + return getJavaType().unwrap( coerce, unwrapType, wrapperOptions ); + } + } + else { + return getJavaType().unwrap( (T) value, unwrapType, wrapperOptions ); } - - return getJavaType().unwrap( (T) value, unwrapType, wrapperOptions ); } }