diff --git a/hibernate-core/src/main/java/org/hibernate/boot/internal/InFlightMetadataCollectorImpl.java b/hibernate-core/src/main/java/org/hibernate/boot/internal/InFlightMetadataCollectorImpl.java index c53f4918856f..8076e10d3659 100644 --- a/hibernate-core/src/main/java/org/hibernate/boot/internal/InFlightMetadataCollectorImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/boot/internal/InFlightMetadataCollectorImpl.java @@ -114,6 +114,7 @@ import java.util.function.Function; import java.util.function.Supplier; +import static java.util.Collections.emptyList; import static org.hibernate.boot.model.naming.Identifier.toIdentifier; import static org.hibernate.boot.model.relational.internal.SqlStringGenerationContextImpl.fromExplicit; import static org.hibernate.cfg.MappingSettings.DEFAULT_CATALOG; @@ -168,7 +169,7 @@ public class InFlightMetadataCollectorImpl private final Map fetchProfileMap = new HashMap<>(); private final Map idGeneratorDefinitionMap = new HashMap<>(); - private Map sqlFunctionMap; + private final Map sqlFunctionMap; final ConfigurationService configurationService; @@ -198,20 +199,20 @@ public InFlightMetadataCollectorImpl( globalRegistrations = new GlobalRegistrationsImpl( bootstrapContext.getModelsContext(), bootstrapContext ); persistenceUnitMetadata = new PersistenceUnitMetadataImpl(); - for ( Map.Entry sqlFunctionEntry : bootstrapContext.getSqlFunctions().entrySet() ) { - if ( sqlFunctionMap == null ) { - // we need this to be a ConcurrentHashMap for the one we ultimately pass along to the SF - // but is this the reference that gets passed along? - sqlFunctionMap = new ConcurrentHashMap<>( 16, .75f, 1 ); - } - sqlFunctionMap.put( sqlFunctionEntry.getKey(), sqlFunctionEntry.getValue() ); - } + // we need this to be a ConcurrentHashMap for the one we ultimately pass along to the SF, + // but is this the reference that gets passed along? + sqlFunctionMap = new ConcurrentHashMap<>( bootstrapContext.getSqlFunctions() ); - bootstrapContext.getAuxiliaryDatabaseObjectList().forEach( getDatabase()::addAuxiliaryDatabaseObject ); + bootstrapContext.getAuxiliaryDatabaseObjectList() + .forEach( getDatabase()::addAuxiliaryDatabaseObject ); configurationService = bootstrapContext.getConfigurationService(); } + private Dialect getDialect() { + return getDatabase().getJdbcEnvironment().getDialect(); + } + @Override public UUID getUUID() { return null; @@ -289,8 +290,10 @@ public Set getMappedSuperclassMappingsCopy() { @Override public void initSessionFactory(SessionFactoryImplementor sessionFactory) { throw new UnsupportedOperationException( - "You should not be building a SessionFactory from an in-flight metadata collector; and of course " + - "we should better segment this in the API :)" + """ + You should not be building a SessionFactory from an in-flight metadata collector; \ + and of course we should better segment this in the API :) + """ ); } @@ -325,7 +328,7 @@ public void registerEmbeddableSubclass(ClassDetails superclass, ClassDetails sub @Override public List getEmbeddableSubclasses(ClassDetails superclass) { final List subclasses = embeddableSubtypes.get( superclass ); - return subclasses != null ? subclasses : List.of(); + return subclasses != null ? subclasses : emptyList(); } @Override @@ -338,16 +341,20 @@ public DiscriminatorType resolveEmbeddableDiscriminatorType( @Override public SessionFactoryBuilder getSessionFactoryBuilder() { throw new UnsupportedOperationException( - "You should not be building a SessionFactory from an in-flight metadata collector; and of course " + - "we should better segment this in the API :)" + """ + You should not be building a SessionFactory from an in-flight metadata collector; \ + and of course we should better segment this in the API :) + """ ); } @Override public SessionFactoryImplementor buildSessionFactory() { throw new UnsupportedOperationException( - "You should not be building a SessionFactory from an in-flight metadata collector; and of course " + - "we should better segment this in the API :)" + """ + You should not be building a SessionFactory from an in-flight metadata collector; \ + and of course we should better segment this in the API :) + """ ); } @@ -377,23 +384,19 @@ public void addEntityBinding(PersistentClass persistentClass) throws DuplicateMa throw new DuplicateMappingException( DuplicateMappingException.Type.ENTITY, entityName ); } - final PersistentClass matchingPersistentClass = entityBindingMap.values() - .stream() - .filter( existingPersistentClass -> existingPersistentClass.getJpaEntityName().equals( jpaEntityName ) ) - .findFirst() - .orElse( null ); - - if ( matchingPersistentClass != null ) { - throw new DuplicateMappingException( - String.format( - "Entity classes [%s] and [%s] share the entity name '%s' (entity names must be distinct)", - matchingPersistentClass.getClassName(), - persistentClass.getClassName(), - jpaEntityName - ), - DuplicateMappingException.Type.ENTITY, - jpaEntityName - ); + for ( var existingPersistentClass : entityBindingMap.values() ) { + if ( existingPersistentClass.getJpaEntityName().equals( jpaEntityName ) ) { + throw new DuplicateMappingException( + String.format( + "Entity classes [%s] and [%s] share the entity name '%s' (entity names must be distinct)", + existingPersistentClass.getClassName(), + persistentClass.getClassName(), + jpaEntityName + ), + DuplicateMappingException.Type.ENTITY, + jpaEntityName + ); + } } entityBindingMap.put( entityName, persistentClass ); @@ -1018,24 +1021,20 @@ public String getIdentifierPropertyName(String entityName) throws MappingExcepti if ( persistentClass == null ) { throw new MappingException( "persistent class not known: " + entityName ); } - if ( !persistentClass.hasIdentifierProperty() ) { - return null; - } - return persistentClass.getIdentifierProperty().getName(); + return persistentClass.hasIdentifierProperty() + ? persistentClass.getIdentifierProperty().getName() + : null; } @Override public org.hibernate.type.Type getReferencedPropertyType(String entityName, String propertyName) throws MappingException { final PersistentClass persistentClass = entityBindingMap.get( entityName ); if ( persistentClass == null ) { - throw new MappingException( "persistent class not known: " + entityName ); + throw new MappingException( "Persistent class not known: " + entityName ); } - Property prop = persistentClass.getReferencedProperty( propertyName ); + final Property prop = persistentClass.getReferencedProperty( propertyName ); if ( prop == null ) { - throw new MappingException( - "property not known: " + - entityName + '.' + propertyName - ); + throw new MappingException( "Property not known: " + entityName + '.' + propertyName ); } return prop.getType(); } @@ -1094,8 +1093,7 @@ private TableColumnNameBinding(String tableName) { } public void addBinding(Identifier logicalName, Column physicalColumn) { - final String physicalNameString = physicalColumn.getQuotedName( getDatabase().getJdbcEnvironment().getDialect() ); - + final String physicalNameString = physicalColumn.getQuotedName( getDialect() ); bindLogicalToPhysical( logicalName, physicalNameString ); bindPhysicalToLogical( logicalName, physicalNameString ); } @@ -1153,10 +1151,11 @@ public void addColumnNameBinding(Table table, String logicalName, Column column) @Override public void addColumnNameBinding(Table table, Identifier logicalName, Column column) throws DuplicateMappingException { - TableColumnNameBinding binding = null; + TableColumnNameBinding binding; if ( columnNameBindingByTableMap == null ) { columnNameBindingByTableMap = new HashMap<>(); + binding = null; } else { binding = columnNameBindingByTableMap.get( table ); @@ -1199,7 +1198,6 @@ public String getPhysicalColumnName(Table table, Identifier logicalName) throws return physicalName; } } - currentTable = currentTable instanceof DenormalizedTable denormalizedTable ? denormalizedTable.getIncludedTable() @@ -1219,20 +1217,17 @@ public String getLogicalColumnName(Table table, String physicalName) throws Mapp @Override public String getLogicalColumnName(Table table, Identifier physicalName) throws MappingException { - final String physicalNameString = physicalName.render( getDatabase().getJdbcEnvironment().getDialect() ); + final String physicalNameString = physicalName.render( getDialect() ); Identifier logicalName = null; - Table currentTable = table; while ( currentTable != null ) { final TableColumnNameBinding binding = columnNameBindingByTableMap.get( currentTable ); - if ( binding != null ) { logicalName = binding.physicalToLogical.get( physicalNameString ); if ( logicalName != null ) { break; } } - currentTable = currentTable instanceof DenormalizedTable denormalizedTable ? denormalizedTable.getIncludedTable() @@ -1244,6 +1239,7 @@ public String getLogicalColumnName(Table table, Identifier physicalName) throws throw new MappingException( "Unable to find column with physical name '" + physicalNameString + "' in table '" + table.getName() + "'" ); } + return logicalName.render(); } @@ -1256,13 +1252,8 @@ public void addAuxiliaryDatabaseObject(AuxiliaryDatabaseObject auxiliaryDatabase @Override public AnnotatedClassType getClassType(ClassDetails clazz) { - AnnotatedClassType type = annotatedClassTypeMap.get( clazz.getName() ); - if ( type == null ) { - return addClassType( clazz ); - } - else { - return type; - } + final AnnotatedClassType type = annotatedClassTypeMap.get( clazz.getName() ); + return type == null ? addClassType( clazz ) : type; } @Override @@ -1309,10 +1300,7 @@ public void addMappedSuperclass(Class type, MappedSuperclass mappedSuperclass @Override public MappedSuperclass getMappedSuperclass(Class type) { - if ( mappedSuperClasses == null ) { - return null; - } - return mappedSuperClasses.get( type ); + return mappedSuperClasses == null ? null : mappedSuperClasses.get( type ); } @Override @@ -1320,9 +1308,10 @@ public PropertyData getPropertyAnnotatedWithMapsId(ClassDetails entityType, Stri if ( propertiesAnnotatedWithMapsId == null ) { return null; } - - final Map map = propertiesAnnotatedWithMapsId.get( entityType ); - return map == null ? null : map.get( propertyName ); + else { + final var map = propertiesAnnotatedWithMapsId.get( entityType ); + return map == null ? null : map.get( propertyName ); + } } @Override @@ -1330,7 +1319,6 @@ public void addPropertyAnnotatedWithMapsId(ClassDetails entityType, PropertyData if ( propertiesAnnotatedWithMapsId == null ) { propertiesAnnotatedWithMapsId = new HashMap<>(); } - propertiesAnnotatedWithMapsId.computeIfAbsent( entityType, k -> new HashMap<>() ) .put( property.getAttributeMember().getDirectAnnotationUsage( MapsId.class ).value(), property ); } @@ -1340,9 +1328,10 @@ public PropertyData getPropertyAnnotatedWithIdAndToOne(ClassDetails entityType, if ( propertiesAnnotatedWithIdAndToOne == null ) { return null; } - - final Map map = propertiesAnnotatedWithIdAndToOne.get( entityType ); - return map == null ? null : map.get( propertyName ); + else { + final var map = propertiesAnnotatedWithIdAndToOne.get( entityType ); + return map == null ? null : map.get( propertyName ); + } } @Override @@ -1350,7 +1339,6 @@ public void addToOneAndIdProperty(ClassDetails entityType, PropertyData property if ( propertiesAnnotatedWithIdAndToOne == null ) { propertiesAnnotatedWithIdAndToOne = new HashMap<>(); } - propertiesAnnotatedWithIdAndToOne.computeIfAbsent( entityType, k -> new HashMap<>() ) .put( property.getPropertyName(), property ); } @@ -1795,10 +1783,8 @@ public void processSecondPasses(MetadataBuildingContext buildingContext) { private void processValueResolvers(MetadataBuildingContext buildingContext) { if ( valueResolvers != null ) { while ( !valueResolvers.isEmpty() ) { - final boolean anyRemoved = valueResolvers.removeIf( - resolver -> resolver.apply( buildingContext ) - ); - + final boolean anyRemoved = + valueResolvers.removeIf( resolver -> resolver.apply( buildingContext ) ); if ( !anyRemoved ) { throw new MappingException( "Unable to complete initialization of boot meta-model" ); } @@ -1818,49 +1804,48 @@ private void processSecondPasses(ArrayList secondPasses) { private void processFkSecondPassesInOrder() { if ( fkSecondPassList == null || fkSecondPassList.isEmpty() ) { processSecondPasses( secondaryTableFromAnnotationSecondPassesList ); - return; - } - - // split FkSecondPass instances into primary key and non primary key FKs. - // While doing so build a map of class names to FkSecondPass instances depending on this class. - final Map> isADependencyOf = new HashMap<>(); - final List endOfQueueFkSecondPasses = new ArrayList<>( fkSecondPassList.size() ); - for ( FkSecondPass sp : fkSecondPassList ) { - if ( sp.isInPrimaryKey() ) { - final String referenceEntityName = sp.getReferencedEntityName(); - final PersistentClass classMapping = getEntityBinding( referenceEntityName ); - if ( classMapping == null ) { - throw new HibernateException( - "Primary key referenced an unknown entity : " + referenceEntityName - ); + } + else { + // split FkSecondPass instances into primary key and non primary key FKs. + // While doing so build a map of class names to FkSecondPass instances depending on this class. + final Map> isADependencyOf = new HashMap<>(); + final List endOfQueueFkSecondPasses = new ArrayList<>( fkSecondPassList.size() ); + for ( FkSecondPass sp : fkSecondPassList ) { + if ( sp.isInPrimaryKey() ) { + final String referencedEntityName = sp.getReferencedEntityName(); + final PersistentClass classMapping = getEntityBinding( referencedEntityName ); + if ( classMapping == null ) { + throw new HibernateException("Primary key referenced an unknown entity: " + + referencedEntityName ); + } + final String dependentTable = classMapping.getTable().getQualifiedTableName().render(); + if ( !isADependencyOf.containsKey( dependentTable ) ) { + isADependencyOf.put( dependentTable, new HashSet<>() ); + } + isADependencyOf.get( dependentTable ).add( sp ); } - final String dependentTable = classMapping.getTable().getQualifiedTableName().render(); - if ( !isADependencyOf.containsKey( dependentTable ) ) { - isADependencyOf.put( dependentTable, new HashSet<>() ); + else { + endOfQueueFkSecondPasses.add( sp ); } - isADependencyOf.get( dependentTable ).add( sp ); } - else { - endOfQueueFkSecondPasses.add( sp ); - } - } - // using the isADependencyOf map we order the FkSecondPass recursively instances into the right order for processing - final List orderedFkSecondPasses = new ArrayList<>( fkSecondPassList.size() ); - for ( String tableName : isADependencyOf.keySet() ) { - buildRecursiveOrderedFkSecondPasses( orderedFkSecondPasses, isADependencyOf, tableName, tableName ); - } + // using the isADependencyOf map we order the FkSecondPass recursively instances into the right order for processing + final List orderedFkSecondPasses = new ArrayList<>( fkSecondPassList.size() ); + for ( String tableName : isADependencyOf.keySet() ) { + buildRecursiveOrderedFkSecondPasses( orderedFkSecondPasses, isADependencyOf, tableName, tableName ); + } - // process the ordered FkSecondPasses - for ( FkSecondPass sp : orderedFkSecondPasses ) { - sp.doSecondPass( getEntityBindingMap() ); - } + // process the ordered FkSecondPasses + for ( FkSecondPass sp : orderedFkSecondPasses ) { + sp.doSecondPass( getEntityBindingMap() ); + } - processSecondPasses( secondaryTableFromAnnotationSecondPassesList ); + processSecondPasses( secondaryTableFromAnnotationSecondPassesList ); - processEndOfQueue( endOfQueueFkSecondPasses ); + processEndOfQueue( endOfQueueFkSecondPasses ); - fkSecondPassList.clear(); + fkSecondPassList.clear(); + } } /** @@ -1918,7 +1903,8 @@ private void processEndOfQueue(List endOfQueueFkSecondPasses) { } } } - stopProcess = failingSecondPasses.isEmpty() || failingSecondPasses.size() == endOfQueueFkSecondPasses.size(); + stopProcess = failingSecondPasses.isEmpty() + || failingSecondPasses.size() == endOfQueueFkSecondPasses.size(); endOfQueueFkSecondPasses = failingSecondPasses; } if ( !endOfQueueFkSecondPasses.isEmpty() ) { @@ -1940,7 +1926,7 @@ protected void secondPassCompileForeignKeys(Table table, Set done, M throws MappingException { table.createForeignKeys( buildingContext ); - final Dialect dialect = getDatabase().getJdbcEnvironment().getDialect(); + final Dialect dialect = getDialect(); for ( ForeignKey foreignKey : table.getForeignKeyCollection() ) { if ( !done.contains( foreignKey ) ) { done.add( foreignKey ); @@ -1955,8 +1941,9 @@ protected void secondPassCompileForeignKeys(Table table, Set done, M foreignKey.setReferencedTable( referencedClass.getTable() ); } - final Identifier nameIdentifier = getMetadataBuildingOptions().getImplicitNamingStrategy() - .determineForeignKeyName( new ForeignKeyNameSource( foreignKey, table, buildingContext ) ); + final Identifier nameIdentifier = + getMetadataBuildingOptions().getImplicitNamingStrategy() + .determineForeignKeyName( new ForeignKeyNameSource( foreignKey, table, buildingContext ) ); foreignKey.setName( nameIdentifier.render( dialect ) ); foreignKey.alignColumns(); @@ -2004,37 +1991,35 @@ private void processNaturalIdUniqueKeyBinders() { } private void processCachingOverrides() { - if ( bootstrapContext.getCacheRegionDefinitions() == null ) { - return; - } - - for ( CacheRegionDefinition cacheRegionDefinition : bootstrapContext.getCacheRegionDefinitions() ) { - if ( cacheRegionDefinition.regionType() == CacheRegionDefinition.CacheRegionType.ENTITY ) { - final PersistentClass entityBinding = getEntityBinding( cacheRegionDefinition.role() ); - if ( entityBinding == null ) { - throw new HibernateException( - "Cache override referenced an unknown entity : " + cacheRegionDefinition.role() - ); - } - if ( !( entityBinding instanceof RootClass rootClass ) ) { - throw new HibernateException( - "Cache override referenced a non-root entity : " + cacheRegionDefinition.role() - ); + if ( bootstrapContext.getCacheRegionDefinitions() != null ) { + for ( CacheRegionDefinition cacheRegionDefinition : bootstrapContext.getCacheRegionDefinitions() ) { + if ( cacheRegionDefinition.regionType() == CacheRegionDefinition.CacheRegionType.ENTITY ) { + final PersistentClass entityBinding = getEntityBinding( cacheRegionDefinition.role() ); + if ( entityBinding == null ) { + throw new HibernateException( + "Cache override referenced an unknown entity : " + cacheRegionDefinition.role() + ); + } + if ( !(entityBinding instanceof RootClass rootClass) ) { + throw new HibernateException( + "Cache override referenced a non-root entity : " + cacheRegionDefinition.role() + ); + } + entityBinding.setCached( true ); + rootClass.setCacheRegionName( cacheRegionDefinition.region() ); + rootClass.setCacheConcurrencyStrategy( cacheRegionDefinition.usage() ); + rootClass.setLazyPropertiesCacheable( cacheRegionDefinition.cacheLazy() ); } - entityBinding.setCached( true ); - rootClass.setCacheRegionName( cacheRegionDefinition.region() ); - rootClass.setCacheConcurrencyStrategy( cacheRegionDefinition.usage() ); - rootClass.setLazyPropertiesCacheable( cacheRegionDefinition.cacheLazy() ); - } - else if ( cacheRegionDefinition.regionType() == CacheRegionDefinition.CacheRegionType.COLLECTION ) { - final Collection collectionBinding = getCollectionBinding( cacheRegionDefinition.role() ); - if ( collectionBinding == null ) { - throw new HibernateException( - "Cache override referenced an unknown collection role : " + cacheRegionDefinition.role() - ); + else if ( cacheRegionDefinition.regionType() == CacheRegionDefinition.CacheRegionType.COLLECTION ) { + final Collection collectionBinding = getCollectionBinding( cacheRegionDefinition.role() ); + if ( collectionBinding == null ) { + throw new HibernateException( + "Cache override referenced an unknown collection role : " + cacheRegionDefinition.role() + ); + } + collectionBinding.setCacheRegionName( cacheRegionDefinition.region() ); + collectionBinding.setCacheConcurrencyStrategy( cacheRegionDefinition.usage() ); } - collectionBinding.setCacheRegionName( cacheRegionDefinition.region() ); - collectionBinding.setCacheConcurrencyStrategy( cacheRegionDefinition.usage() ); } } } @@ -2086,7 +2071,7 @@ public MetadataImpl buildMetadataInstance(MetadataBuildingContext buildingContex private void processExportableProducers() { // for now we only handle id generators as ExportableProducers - final Dialect dialect = getDatabase().getJdbcEnvironment().getDialect(); + final Dialect dialect = getDialect(); for ( PersistentClass entityBinding : entityBindingMap.values() ) { entityBinding.assignCheckConstraintsToTable( dialect, bootstrapContext.getTypeConfiguration() ); @@ -2118,9 +2103,9 @@ private void handleIdentifierValueBinding( identifierValueBinding.createGenerator( dialect, entityBinding, identifierProperty, this ); } catch (MappingException e) { - // ignore this for now. The reasoning being "non-reflective" binding as needed - // by tools. We want to hold off requiring classes being present until we - // try to build a SF. Here, just building the Metadata, it is "ok" for an + // Ignore this for now, the reasoning being "non-reflective" binding as needed + // by tools. We want to hold off requiring classes being present until we + // try to build the SF. Here, just building the Metadata, it is "ok" for an // exception to occur, the same exception will happen later as we build the SF. log.debugf( "Ignoring exception thrown when trying to build IdentifierGenerator as part of Metadata building", e ); } diff --git a/hibernate-core/src/main/java/org/hibernate/boot/internal/SessionFactoryBuilderImpl.java b/hibernate-core/src/main/java/org/hibernate/boot/internal/SessionFactoryBuilderImpl.java index c73391ebe3a4..d76cbf40f42c 100644 --- a/hibernate-core/src/main/java/org/hibernate/boot/internal/SessionFactoryBuilderImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/boot/internal/SessionFactoryBuilderImpl.java @@ -4,7 +4,6 @@ */ package org.hibernate.boot.internal; -import java.util.Map; import java.util.function.Supplier; import org.hibernate.CustomEntityDirtinessStrategy; @@ -59,7 +58,7 @@ public SessionFactoryBuilderImpl(MetadataImplementor metadata, SessionFactoryOpt this.bootstrapContext = context; if ( metadata.getSqlFunctionMap() != null ) { - for ( Map.Entry sqlFunctionEntry : metadata.getSqlFunctionMap().entrySet() ) { + for ( var sqlFunctionEntry : metadata.getSqlFunctionMap().entrySet() ) { applySqlFunction( sqlFunctionEntry.getKey(), sqlFunctionEntry.getValue() ); } } diff --git a/hibernate-core/src/main/java/org/hibernate/boot/model/internal/ColumnsBuilder.java b/hibernate-core/src/main/java/org/hibernate/boot/model/internal/ColumnsBuilder.java index 2920b00c8534..511c67105b1e 100644 --- a/hibernate-core/src/main/java/org/hibernate/boot/model/internal/ColumnsBuilder.java +++ b/hibernate-core/src/main/java/org/hibernate/boot/model/internal/ColumnsBuilder.java @@ -91,7 +91,6 @@ public ColumnsBuilder extractMetadata() { columns = buildColumnFromAnnotation( columnAnn, property.getDirectAnnotationUsage( FractionalSeconds.class ), -// comment, nullability, propertyHolder, inferredData, @@ -149,7 +148,6 @@ else if ( joinColumns == null //useful for collection of embedded elements columns = buildColumnFromNoAnnotation( property.getDirectAnnotationUsage( FractionalSeconds.class ), -// comment, nullability, propertyHolder, inferredData, @@ -196,7 +194,7 @@ private AnnotatedJoinColumns buildDefaultJoinColumnsForToOne( private AnnotatedJoinColumns buildExplicitJoinColumns(MemberDetails property, PropertyData inferredData) { // process @JoinColumns before @Columns to handle collection of entities properly - final JoinColumn[] joinColumnAnnotations = getJoinColumnAnnotations( property, inferredData ); + final JoinColumn[] joinColumnAnnotations = getJoinColumnAnnotations( property ); if ( joinColumnAnnotations != null ) { return AnnotatedJoinColumns.buildJoinColumns( joinColumnAnnotations, @@ -208,7 +206,7 @@ private AnnotatedJoinColumns buildExplicitJoinColumns(MemberDetails property, Pr ); } - final JoinColumnOrFormula[] joinColumnOrFormulaAnnotations = joinColumnOrFormulaAnnotations( property, inferredData ); + final JoinColumnOrFormula[] joinColumnOrFormulaAnnotations = joinColumnOrFormulaAnnotations( property ); if ( joinColumnOrFormulaAnnotations != null ) { return AnnotatedJoinColumns.buildJoinColumnsOrFormulas( joinColumnOrFormulaAnnotations, @@ -234,20 +232,16 @@ private AnnotatedJoinColumns buildExplicitJoinColumns(MemberDetails property, Pr return null; } - private JoinColumnOrFormula[] joinColumnOrFormulaAnnotations(MemberDetails property, PropertyData inferredData) { + private JoinColumnOrFormula[] joinColumnOrFormulaAnnotations(MemberDetails property) { final ModelsContext modelsContext = buildingContext.getBootstrapContext().getModelsContext(); final JoinColumnOrFormula[] annotations = property.getRepeatedAnnotationUsages( HibernateAnnotations.JOIN_COLUMN_OR_FORMULA, modelsContext ); - if ( isNotEmpty( annotations ) ) { - return annotations; - } - - return null; + return isNotEmpty( annotations ) ? annotations : null; } - private JoinColumn[] getJoinColumnAnnotations(MemberDetails property, PropertyData inferredData) { + private JoinColumn[] getJoinColumnAnnotations(MemberDetails property) { final ModelsContext modelsContext = buildingContext.getBootstrapContext().getModelsContext(); final JoinColumn[] joinColumns = property.getRepeatedAnnotationUsages( @@ -257,8 +251,7 @@ private JoinColumn[] getJoinColumnAnnotations(MemberDetails property, PropertyDa if ( isNotEmpty( joinColumns ) ) { return joinColumns; } - - if ( property.hasDirectAnnotationUsage( MapsId.class ) ) { + else if ( property.hasDirectAnnotationUsage( MapsId.class ) ) { // inelegant solution to HHH-16463, let the PrimaryKeyJoinColumn // masquerade as a regular JoinColumn (when a @OneToOne maps to // the primary key of the child table, it's more elegant and more @@ -275,9 +268,13 @@ private JoinColumn[] getJoinColumnAnnotations(MemberDetails property, PropertyDa } return adapters; } + else { + return null; + } + } + else { + return null; } - - return null; } /** @@ -285,9 +282,10 @@ private JoinColumn[] getJoinColumnAnnotations(MemberDetails property, PropertyDa */ AnnotatedColumns overrideColumnFromMapperOrMapsIdProperty(PropertyData override) { if ( override != null ) { - final AnnotatedJoinColumns joinColumns = buildExplicitJoinColumns( override.getAttributeMember(), override ); + final MemberDetails attributeMember = override.getAttributeMember(); + final AnnotatedJoinColumns joinColumns = buildExplicitJoinColumns( attributeMember, override ); return joinColumns == null - ? buildDefaultJoinColumnsForToOne( override.getAttributeMember(), override ) + ? buildDefaultJoinColumnsForToOne( attributeMember, override ) : joinColumns; } else { diff --git a/hibernate-core/src/main/java/org/hibernate/engine/jdbc/connections/internal/DriverManagerConnectionProviderImpl.java b/hibernate-core/src/main/java/org/hibernate/engine/jdbc/connections/internal/DriverManagerConnectionProviderImpl.java index da8dc0758aae..3895f63f7688 100644 --- a/hibernate-core/src/main/java/org/hibernate/engine/jdbc/connections/internal/DriverManagerConnectionProviderImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/engine/jdbc/connections/internal/DriverManagerConnectionProviderImpl.java @@ -9,7 +9,6 @@ import java.sql.DriverManager; import java.sql.SQLException; import java.util.Enumeration; -import java.util.Iterator; import java.util.Map; import java.util.Properties; import java.util.concurrent.ConcurrentLinkedQueue; @@ -477,7 +476,7 @@ protected void closeConnection(Connection conn, Throwable t) { public void close() throws SQLException { try { - int allocationCount = allConnections.size() - availableConnections.size(); + final int allocationCount = allConnections.size() - availableConnections.size(); if (allocationCount > 0) { ConnectionInfoLogger.INSTANCE.error( "Connection leak detected: there are " + allocationCount + " unclosed connections upon shutting down pool " + getUrl()); } @@ -653,8 +652,7 @@ private void validateConnections(ConnectionValidator validator) { statelock.writeLock().lock(); try { RuntimeException ex = null; - for ( Iterator iterator = pool.allConnections.iterator(); iterator.hasNext(); ) { - final Connection connection = iterator.next(); + for ( Connection connection : pool.allConnections ) { SQLException e = null; boolean isValid = false; try { diff --git a/hibernate-core/src/main/java/org/hibernate/persister/entity/DiscriminatorType.java b/hibernate-core/src/main/java/org/hibernate/persister/entity/DiscriminatorType.java index b909e603754c..b51978f7604d 100644 --- a/hibernate-core/src/main/java/org/hibernate/persister/entity/DiscriminatorType.java +++ b/hibernate-core/src/main/java/org/hibernate/persister/entity/DiscriminatorType.java @@ -126,32 +126,27 @@ public void nullSafeSet( } @Override - public String toLoggableString(Object value, SessionFactoryImplementor factory) throws HibernateException { + public String toLoggableString(Object value, SessionFactoryImplementor factory) { return value == null ? "[null]" : value.toString(); } @Override - public Object deepCopy(Object value, SessionFactoryImplementor factory) - throws HibernateException { + public Object deepCopy(Object value, SessionFactoryImplementor factory) { return value; } @Override - public Object replace(Object original, Object target, SharedSessionContractImplementor session, Object owner, Map copyCache) - throws HibernateException { + public Object replace(Object original, Object target, SharedSessionContractImplementor session, Object owner, Map copyCache) { return original; } @Override public boolean[] toColumnNullness(Object value, MappingContext mapping) { - return value == null - ? ArrayHelper.FALSE - : ArrayHelper.TRUE; + return value == null ? ArrayHelper.FALSE : ArrayHelper.TRUE; } @Override - public boolean isDirty(Object old, Object current, boolean[] checkable, SharedSessionContractImplementor session) - throws HibernateException { + public boolean isDirty(Object old, Object current, boolean[] checkable, SharedSessionContractImplementor session) { return Objects.equals( old, current ); } diff --git a/hibernate-core/src/main/java/org/hibernate/persister/entity/mutation/AbstractDeleteCoordinator.java b/hibernate-core/src/main/java/org/hibernate/persister/entity/mutation/AbstractDeleteCoordinator.java index 954dee81df7a..44012b9c36e6 100644 --- a/hibernate-core/src/main/java/org/hibernate/persister/entity/mutation/AbstractDeleteCoordinator.java +++ b/hibernate-core/src/main/java/org/hibernate/persister/entity/mutation/AbstractDeleteCoordinator.java @@ -13,7 +13,6 @@ import org.hibernate.engine.jdbc.mutation.ParameterUsage; import org.hibernate.engine.jdbc.mutation.group.PreparedStatementDetails; import org.hibernate.engine.spi.EntityEntry; -import org.hibernate.engine.spi.PersistenceContext; import org.hibernate.engine.spi.SessionFactoryImplementor; import org.hibernate.engine.spi.SharedSessionContractImplementor; import org.hibernate.metamodel.mapping.AttributeMapping; @@ -74,12 +73,11 @@ public void delete( SharedSessionContractImplementor session) { boolean isImpliedOptimisticLocking = entityPersister().optimisticLockStyle().isAllOrDirty(); - final PersistenceContext persistenceContext = session.getPersistenceContextInternal(); - final EntityEntry entry = persistenceContext.getEntry( entity ); + final EntityEntry entry = session.getPersistenceContextInternal().getEntry( entity ); final Object[] loadedState = entry != null && isImpliedOptimisticLocking ? entry.getLoadedState() : null; final Object rowId = entry != null ? entry.getRowId() : null; - if ( ( isImpliedOptimisticLocking && loadedState != null ) || ( rowId == null && entityPersister().hasRowId() ) ) { + if ( isImpliedOptimisticLocking && loadedState != null || rowId == null && entityPersister().hasRowId() ) { doDynamicDelete( entity, id, rowId, loadedState, session ); } else { diff --git a/hibernate-core/src/main/java/org/hibernate/type/AbstractStandardBasicType.java b/hibernate-core/src/main/java/org/hibernate/type/AbstractStandardBasicType.java index 5e967b29f6a5..d41f3de19ffc 100644 --- a/hibernate-core/src/main/java/org/hibernate/type/AbstractStandardBasicType.java +++ b/hibernate-core/src/main/java/org/hibernate/type/AbstractStandardBasicType.java @@ -298,11 +298,10 @@ public final void beforeAssemble(Serializable cached, SharedSessionContractImple @Override @SuppressWarnings("unchecked") public final Object replace(Object original, Object target, SharedSessionContractImplementor session, Object owner, Map copyCache) { - if ( original == null && target == null ) { - return null; - } + return original == null && target == null + ? null + : javaType.getReplacement( (T) original, (T) target, session ); - return javaType.getReplacement( (T) original, (T) target, session ); } @Override diff --git a/hibernate-core/src/main/java/org/hibernate/type/ComponentType.java b/hibernate-core/src/main/java/org/hibernate/type/ComponentType.java index da26730cabe8..adea047c1c08 100644 --- a/hibernate-core/src/main/java/org/hibernate/type/ComponentType.java +++ b/hibernate-core/src/main/java/org/hibernate/type/ComponentType.java @@ -355,9 +355,7 @@ public boolean isModified( @Override public void nullSafeSet(PreparedStatement st, Object value, int begin, SharedSessionContractImplementor session) throws HibernateException, SQLException { - - Object[] subvalues = nullSafeGetValues( value ); - + final Object[] subvalues = nullSafeGetValues( value ); for ( int i = 0; i < propertySpan; i++ ) { propertyTypes[i].nullSafeSet( st, subvalues[i], begin, session ); begin += propertyTypes[i].getColumnSpan( session.getFactory().getRuntimeMetamodels() ); @@ -372,7 +370,6 @@ public void nullSafeSet( boolean[] settable, SharedSessionContractImplementor session) throws HibernateException, SQLException { - final Object[] subvalues = nullSafeGetValues( value ); int loc = 0; for ( int i = 0; i < propertySpan; i++ ) { @@ -481,18 +478,19 @@ public String toLoggableString(Object value, SessionFactoryImplementor factory) if ( value == null ) { return "null"; } - - final Map result = new HashMap<>(); - final Object[] values = getPropertyValues( value ); - for ( int i = 0; i < propertyTypes.length; i++ ) { - if ( values[i] == LazyPropertyInitializer.UNFETCHED_PROPERTY ) { - result.put( propertyNames[i], "" ); - } - else { - result.put( propertyNames[i], propertyTypes[i].toLoggableString( values[i], factory ) ); + else { + final Map result = new HashMap<>(); + final Object[] values = getPropertyValues( value ); + for ( int i = 0; i < propertyTypes.length; i++ ) { + if ( values[i] == LazyPropertyInitializer.UNFETCHED_PROPERTY ) { + result.put( propertyNames[i], "" ); + } + else { + result.put( propertyNames[i], propertyTypes[i].toLoggableString( values[i], factory ) ); + } } + return unqualify( getName() ) + result; } - return unqualify( getName() ) + result; } @Override @@ -505,22 +503,23 @@ public Object deepCopy(Object component, SessionFactoryImplementor factory) { if ( component == null ) { return null; } + else { + final Object[] values = getPropertyValues( component ); + for ( int i = 0; i < propertySpan; i++ ) { + values[i] = propertyTypes[i].deepCopy( values[i], factory ); + } - final Object[] values = getPropertyValues( component ); - for ( int i = 0; i < propertySpan; i++ ) { - values[i] = propertyTypes[i].deepCopy( values[i], factory ); - } + final Object result = instantiator( component ).instantiate( () -> values ); - final Object result = instantiator( component ).instantiate( () -> values ); + //not absolutely necessary, but helps for some + //equals()/hashCode() implementations + final PropertyAccess parentAccess = mappingModelPart().getParentInjectionAttributePropertyAccess(); + if ( parentAccess != null ) { + parentAccess.getSetter().set( result, parentAccess.getGetter().get( component ) ); + } - //not absolutely necessary, but helps for some - //equals()/hashCode() implementations - final PropertyAccess parentAccess = mappingModelPart().getParentInjectionAttributePropertyAccess(); - if ( parentAccess != null ) { - parentAccess.getSetter().set( result, parentAccess.getGetter().get( component ) ); + return result; } - - return result; } @Override @@ -530,28 +529,28 @@ public Object replace( SharedSessionContractImplementor session, Object owner, Map copyCache) { - if ( original == null ) { return null; } - - final Object[] originalValues = getPropertyValues( original ); - final Object[] resultValues = getPropertyValues( target ); - final Object[] replacedValues = TypeHelper.replace( - originalValues, - resultValues, - propertyTypes, - session, - owner, - copyCache - ); - - if ( target == null || !isMutable() ) { - return instantiator( original ).instantiate( () -> replacedValues ); - } else { - setPropertyValues( target, replacedValues ); - return target; + final Object[] originalValues = getPropertyValues( original ); + final Object[] resultValues = getPropertyValues( target ); + final Object[] replacedValues = TypeHelper.replace( + originalValues, + resultValues, + propertyTypes, + session, + owner, + copyCache + ); + + if ( target == null || !isMutable() ) { + return instantiator( original ).instantiate( () -> replacedValues ); + } + else { + setPropertyValues( target, replacedValues ); + return target; + } } } @@ -563,28 +562,29 @@ public Object replace( Object owner, Map copyCache, ForeignKeyDirection foreignKeyDirection) { - if ( original == null ) { return null; } - final Object[] originalValues = getPropertyValues( original ); - final Object[] resultValues = getPropertyValues( target ); - final Object[] replacedValues = TypeHelper.replace( - originalValues, - resultValues, - propertyTypes, - session, - owner, - copyCache, - foreignKeyDirection - ); - - if ( target == null || !isMutable() ) { - return instantiator( original ).instantiate( () -> replacedValues ); - } else { - setPropertyValues( target, replacedValues ); - return target; + final Object[] originalValues = getPropertyValues( original ); + final Object[] resultValues = getPropertyValues( target ); + final Object[] replacedValues = TypeHelper.replace( + originalValues, + resultValues, + propertyTypes, + session, + owner, + copyCache, + foreignKeyDirection + ); + + if ( target == null || !isMutable() ) { + return instantiator( original ).instantiate( () -> replacedValues ); + } + else { + setPropertyValues( target, replacedValues ); + return target; + } } } diff --git a/hibernate-core/src/main/java/org/hibernate/type/TypeHelper.java b/hibernate-core/src/main/java/org/hibernate/type/TypeHelper.java index b1f4f07fd8f3..d3dd98cc8450 100644 --- a/hibernate-core/src/main/java/org/hibernate/type/TypeHelper.java +++ b/hibernate-core/src/main/java/org/hibernate/type/TypeHelper.java @@ -108,11 +108,12 @@ public static void replace( final Type[] types = persister.getPropertyTypes(); for ( int i = 0; i < types.length; i++ ) { final Object oldValue = values[i]; - final Object newValue; if ( oldValue != LazyPropertyInitializer.UNFETCHED_PROPERTY - && oldValue != PropertyAccessStrategyBackRefImpl.UNKNOWN - && ( newValue = types[i].replace( values[i], values[i], session, owner, copyCache ) ) != oldValue ) { - persister.setValue( entity, i, newValue ); + && oldValue != PropertyAccessStrategyBackRefImpl.UNKNOWN ) { + final Object newValue = types[i].replace( values[i], values[i], session, owner, copyCache ); + if ( newValue != oldValue ) { + persister.setValue( entity, i, newValue ); + } } } } diff --git a/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/AbstractArrayJavaType.java b/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/AbstractArrayJavaType.java index 1f5d02a685eb..7f30d54221fe 100644 --- a/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/AbstractArrayJavaType.java +++ b/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/AbstractArrayJavaType.java @@ -4,23 +4,23 @@ */ package org.hibernate.type.descriptor.java; -import java.lang.reflect.Array; - import org.hibernate.MappingException; import org.hibernate.dialect.Dialect; import org.hibernate.internal.build.AllowReflection; import org.hibernate.tool.schema.extract.spi.ColumnTypeInformation; -import org.hibernate.type.descriptor.converter.internal.ArrayConverter; import org.hibernate.type.BasicArrayType; import org.hibernate.type.BasicPluralType; import org.hibernate.type.BasicType; import org.hibernate.type.ConvertedBasicArrayType; +import org.hibernate.type.descriptor.converter.internal.ArrayConverter; import org.hibernate.type.descriptor.converter.spi.BasicValueConverter; import org.hibernate.type.descriptor.java.spi.UnknownBasicJavaType; import org.hibernate.type.descriptor.jdbc.JdbcType; import org.hibernate.type.descriptor.jdbc.JdbcTypeIndicators; import org.hibernate.type.spi.TypeConfiguration; +import static java.lang.reflect.Array.newInstance; + @AllowReflection public abstract class AbstractArrayJavaType extends AbstractClassJavaType implements BasicPluralJavaType { @@ -74,29 +74,37 @@ public BasicType resolveType( || elementJavaTypeClass != null && elementJavaTypeClass.isArray() ) { return null; } - final BasicValueConverter valueConverter = elementType.getValueConverter(); + final var valueConverter = elementType.getValueConverter(); return valueConverter == null - ? resolveType( typeConfiguration, dialect, this, elementType, columnTypeInformation, stdIndicators ) - : createTypeUsingConverter( typeConfiguration, dialect, elementType, columnTypeInformation, stdIndicators, valueConverter ); + ? resolveType( typeConfiguration, this, elementType, columnTypeInformation, stdIndicators ) + : createTypeUsingConverter( typeConfiguration, elementType, columnTypeInformation, stdIndicators, valueConverter ); + } + + private static JdbcType arrayJdbcType( + TypeConfiguration typeConfiguration, + BasicType elementType, + ColumnTypeInformation columnTypeInformation, + JdbcTypeIndicators indicators) { + final int arrayTypeCode = + indicators.getPreferredSqlTypeCodeForArray( elementType.getJdbcType().getDefaultSqlTypeCode() ); + return typeConfiguration.getJdbcTypeRegistry() + .resolveTypeConstructorDescriptor( arrayTypeCode, elementType, columnTypeInformation ); } BasicType createTypeUsingConverter( TypeConfiguration typeConfiguration, - Dialect dialect, BasicType elementType, ColumnTypeInformation columnTypeInformation, - JdbcTypeIndicators stdIndicators, + JdbcTypeIndicators indicators, BasicValueConverter valueConverter) { final Class convertedElementClass = valueConverter.getRelationalJavaType().getJavaTypeClass(); - final Class convertedArrayClass = Array.newInstance( convertedElementClass, 0 ).getClass(); - final JavaType relationalJavaType = typeConfiguration.getJavaTypeRegistry().getDescriptor( convertedArrayClass ); + final Class convertedArrayClass = newInstance( convertedElementClass, 0 ).getClass(); + final JavaType relationalJavaType = + typeConfiguration.getJavaTypeRegistry() + .getDescriptor( convertedArrayClass ); return new ConvertedBasicArrayType<>( elementType, - typeConfiguration.getJdbcTypeRegistry().resolveTypeConstructorDescriptor( - stdIndicators.getPreferredSqlTypeCodeForArray( elementType.getJdbcType().getDefaultSqlTypeCode() ), - elementType, - columnTypeInformation - ), + arrayJdbcType( typeConfiguration, elementType, columnTypeInformation, indicators ), this, new ArrayConverter<>( valueConverter, this, relationalJavaType ) ); @@ -104,21 +112,15 @@ BasicType createTypeUsingConverter( BasicType resolveType( TypeConfiguration typeConfiguration, - Dialect dialect, AbstractArrayJavaType arrayJavaType, BasicType elementType, ColumnTypeInformation columnTypeInformation, - JdbcTypeIndicators stdIndicators) { - final JdbcType arrayJdbcType = typeConfiguration.getJdbcTypeRegistry().resolveTypeConstructorDescriptor( - stdIndicators.getPreferredSqlTypeCodeForArray( elementType.getJdbcType().getDefaultSqlTypeCode() ), - elementType, - columnTypeInformation - ); - return typeConfiguration.getBasicTypeRegistry().resolve( - arrayJavaType, - arrayJdbcType, - () -> new BasicArrayType<>( elementType, arrayJdbcType, arrayJavaType ) - ); + JdbcTypeIndicators indicators) { + final JdbcType arrayJdbcType = + arrayJdbcType( typeConfiguration, elementType, columnTypeInformation, indicators ); + return typeConfiguration.getBasicTypeRegistry() + .resolve( arrayJavaType, arrayJdbcType, + () -> new BasicArrayType<>( elementType, arrayJdbcType, arrayJavaType ) ); } } diff --git a/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/ArrayJavaType.java b/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/ArrayJavaType.java index aef0acd0f6cb..ca0a3bcfc59c 100644 --- a/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/ArrayJavaType.java +++ b/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/ArrayJavaType.java @@ -5,7 +5,6 @@ package org.hibernate.type.descriptor.java; import java.io.Serializable; -import java.lang.reflect.Array; import java.sql.SQLException; import java.util.Collection; @@ -24,6 +23,7 @@ import org.hibernate.type.descriptor.jdbc.JdbcTypeIndicators; import org.hibernate.type.spi.TypeConfiguration; +import static java.lang.reflect.Array.newInstance; import static org.hibernate.internal.util.ReflectHelper.arrayClass; /** @@ -67,26 +67,28 @@ public BasicType resolveType( ); } } - final Class elementJavaTypeClass = elementType.getJavaTypeDescriptor().getJavaTypeClass(); + final JavaType elementTypeJavaType = elementType.getJavaTypeDescriptor(); + final Class elementJavaTypeClass = elementTypeJavaType.getJavaTypeClass(); if ( elementType instanceof BasicPluralType - || elementJavaTypeClass != null && elementJavaTypeClass.isArray() - && elementJavaTypeClass != byte[].class ) { + || elementJavaTypeClass != null + && elementJavaTypeClass.isArray() + && elementJavaTypeClass != byte[].class ) { // No support for nested arrays, except for byte[][] return null; } final ArrayJavaType arrayJavaType; - if ( getElementJavaType() == elementType.getJavaTypeDescriptor() ) { + if ( getElementJavaType() == elementTypeJavaType ) { arrayJavaType = this; } else { - arrayJavaType = new ArrayJavaType<>( elementType.getJavaTypeDescriptor() ); + arrayJavaType = new ArrayJavaType<>( elementTypeJavaType ); // Register the array type as that will be resolved in the next step typeConfiguration.getJavaTypeRegistry().addDescriptor( arrayJavaType ); } final BasicValueConverter valueConverter = elementType.getValueConverter(); return valueConverter == null - ? resolveType( typeConfiguration, dialect, arrayJavaType, elementType, columnTypeInformation, stdIndicators ) - : createTypeUsingConverter( typeConfiguration, dialect, elementType, columnTypeInformation, stdIndicators, valueConverter ); + ? resolveType( typeConfiguration, arrayJavaType, elementType, columnTypeInformation, stdIndicators ) + : createTypeUsingConverter( typeConfiguration, elementType, columnTypeInformation, stdIndicators, valueConverter ); } @Override @@ -134,9 +136,7 @@ public int extractHashCode(T[] value) { if ( value == null ) { return 0; } - int result = 1; - for ( T element : value ) { result = 31 * result + ( element == null ? 0 : getElementJavaType().extractHashCode( element ) ); } @@ -159,7 +159,7 @@ public String toString(T[] value) { continue; } sb.append( '"' ); - String valstr = getElementJavaType().toString( v ); + final String valstr = getElementJavaType().toString( v ); // using replaceAll is a shorter, but much slower way to do this for (int i = 0, len = valstr.length(); i < len; i ++ ) { char c = valstr.charAt( i ); @@ -173,8 +173,7 @@ public String toString(T[] value) { glue = ","; } sb.append( '}' ); - final String result = sb.toString(); - return result; + return sb.toString(); } @Override @@ -182,7 +181,7 @@ public T[] fromString(CharSequence charSequence) { if ( charSequence == null ) { return null; } - java.util.ArrayList lst = new java.util.ArrayList<>(); + final java.util.ArrayList lst = new java.util.ArrayList<>(); StringBuilder sb = null; char lastChar = charSequence.charAt( charSequence.length() - 1 ); char firstChar = charSequence.charAt( 0 ); @@ -232,7 +231,7 @@ else if ( c == ',' ) { break; } throw new IllegalArgumentException( "Cannot parse given string into array of strings." - + " Outside of quote, but neither whitespace, comma, array end, nor null found." ); + + " Outside of quote, but neither whitespace, comma, array end, nor null found." ); } } else if ( c == '\\' && i + 2 < len && (charSequence.charAt( i + 1 ) == '\\' || charSequence.charAt( i + 1 ) == '"')) { @@ -242,7 +241,7 @@ else if ( c == '\\' && i + 2 < len && (charSequence.charAt( i + 1 ) == '\\' || c sb.append( c ); } //noinspection unchecked - final T[] result = (T[]) Array.newInstance( getElementJavaType().getJavaTypeClass(), lst.size() ); + final T[] result = (T[]) newInstance( getElementJavaType().getJavaTypeClass(), lst.size() ); for ( int i = 0; i < result.length; i ++ ) { if ( lst.get( i ) != null ) { result[i] = getElementJavaType().fromString( lst.get( i ) ); @@ -270,7 +269,7 @@ else if ( type == BinaryStream.class ) { } else if ( type.isArray() ) { final Class preferredJavaTypeClass = type.getComponentType(); - final Object[] unwrapped = (Object[]) Array.newInstance( preferredJavaTypeClass, value.length ); + final Object[] unwrapped = (Object[]) newInstance( preferredJavaTypeClass, value.length ); for ( int i = 0; i < value.length; i++ ) { unwrapped[i] = getElementJavaType().unwrap( value[i], preferredJavaTypeClass, options ); } @@ -298,10 +297,11 @@ public T[] wrap(X value, WrapperOptions options) { } } + final JavaType elementJavaType = getElementJavaType(); if ( value instanceof Object[] raw ) { - final Class componentClass = getElementJavaType().getJavaTypeClass(); + final Class componentClass = elementJavaType.getJavaTypeClass(); //noinspection unchecked - final T[] wrapped = (T[]) java.lang.reflect.Array.newInstance( componentClass, raw.length ); + final T[] wrapped = (T[]) newInstance( componentClass, raw.length ); if ( componentClass.isAssignableFrom( value.getClass().getComponentType() ) ) { for (int i = 0; i < raw.length; i++) { //noinspection unchecked @@ -310,7 +310,7 @@ public T[] wrap(X value, WrapperOptions options) { } else { for ( int i = 0; i < raw.length; i++ ) { - wrapped[i] = getElementJavaType().wrap( raw[i], options ); + wrapped[i] = elementJavaType.wrap( raw[i], options ); } } return wrapped; @@ -322,20 +322,20 @@ else if ( value instanceof BinaryStream binaryStream ) { // When the value is a BinaryStream, this is a deserialization request return fromBytes( binaryStream.getBytes() ); } - else if ( getElementJavaType().isInstance( value ) ) { + else if ( elementJavaType.isInstance( value ) ) { // Support binding a single element as parameter value //noinspection unchecked - final T[] wrapped = (T[]) java.lang.reflect.Array.newInstance( getElementJavaType().getJavaTypeClass(), 1 ); + final T[] wrapped = (T[]) newInstance( elementJavaType.getJavaTypeClass(), 1 ); //noinspection unchecked wrapped[0] = (T) value; return wrapped; } else if ( value instanceof Collection collection ) { //noinspection unchecked - final T[] wrapped = (T[]) java.lang.reflect.Array.newInstance( getElementJavaType().getJavaTypeClass(), collection.size() ); + final T[] wrapped = (T[]) newInstance( elementJavaType.getJavaTypeClass(), collection.size() ); int i = 0; for ( Object e : collection ) { - wrapped[i++] = getElementJavaType().wrap( e, options ); + wrapped[i++] = elementJavaType.wrap( e, options ); } return wrapped; } @@ -343,29 +343,31 @@ else if ( value instanceof Collection collection ) { throw unknownWrap( value.getClass() ); } - private static byte[] toBytes(T[] value) { - if ( value.getClass().getComponentType().isEnum() ) { - final byte[] array = new byte[value.length]; - for (int i = 0; i < value.length; i++ ) { + private static byte[] toBytes(T[] array) { + if ( array.getClass().getComponentType().isEnum() ) { + final byte[] bytes = new byte[array.length]; + for (int i = 0; i < array.length; i++ ) { + final T value = array[i]; // encode null enum value as -1 - array[i] = value[i] == null ? -1 : (byte) ((Enum) value[i]).ordinal(); + bytes[i] = value == null ? -1 : (byte) ((Enum) value).ordinal(); } - return array; + return bytes; } else { // byte[] can only be requested if the value should be serialized - return SerializationHelper.serialize( value ); + return SerializationHelper.serialize( array ); } } private T[] fromBytes(byte[] bytes) { final Class elementClass = getElementJavaType().getJavaTypeClass(); if ( elementClass.isEnum() ) { - final Object[] array = (Object[]) Array.newInstance( elementClass, bytes.length ); + final T[] enumConstants = elementClass.getEnumConstants(); + final Object[] array = (Object[]) newInstance( elementClass, bytes.length ); for (int i = 0; i < bytes.length; i++ ) { // null enum value was encoded as -1 - array[i] = bytes[i] == -1 ? null : elementClass.getEnumConstants()[bytes[i]]; + array[i] = bytes[i] == -1 ? null : enumConstants[bytes[i]]; } //noinspection unchecked return (T[]) array; @@ -400,7 +402,7 @@ public T[] deepCopy(T[] value) { return null; } //noinspection unchecked - final T[] copy = (T[]) Array.newInstance( componentClass, value.length ); + final T[] copy = (T[]) newInstance( componentClass, value.length ); for ( int i = 0; i < value.length; i ++ ) { copy[ i ] = componentPlan.deepCopy( value[ i ] ); } diff --git a/hibernate-core/src/main/java/org/hibernate/type/descriptor/jdbc/ArrayJdbcType.java b/hibernate-core/src/main/java/org/hibernate/type/descriptor/jdbc/ArrayJdbcType.java index 748276f46e9a..8af039fed718 100644 --- a/hibernate-core/src/main/java/org/hibernate/type/descriptor/jdbc/ArrayJdbcType.java +++ b/hibernate-core/src/main/java/org/hibernate/type/descriptor/jdbc/ArrayJdbcType.java @@ -31,6 +31,7 @@ import org.hibernate.type.internal.ParameterizedTypeImpl; import org.hibernate.type.spi.TypeConfiguration; +import static java.lang.reflect.Array.newInstance; import static org.hibernate.type.descriptor.jdbc.StructHelper.instantiate; /** @@ -62,44 +63,41 @@ public JavaType getJdbcRecommendedJavaTypeMapping( Integer precision, Integer scale, TypeConfiguration typeConfiguration) { - final JavaType elementJavaType = elementJdbcType.getJdbcRecommendedJavaTypeMapping( - precision, - scale, - typeConfiguration - ); - final JavaType javaType = typeConfiguration.getJavaTypeRegistry().resolveDescriptor( - Array.newInstance( elementJavaType.getJavaTypeClass(), 0 ).getClass() - ); + final JavaType elementJavaType = + elementJdbcType.getJdbcRecommendedJavaTypeMapping( precision, scale, typeConfiguration ); + final JavaType javaType = + typeConfiguration.getJavaTypeRegistry() + .resolveDescriptor( newInstance( elementJavaType.getJavaTypeClass(), 0 ).getClass() ); if ( javaType instanceof BasicPluralType ) { //noinspection unchecked return (JavaType) javaType; } - //noinspection unchecked - return (JavaType) javaType.createJavaType( - new ParameterizedTypeImpl( javaType.getJavaTypeClass(), new Type[0], null ), - typeConfiguration - ); + else { + //noinspection unchecked + return (JavaType) javaType.createJavaType( + new ParameterizedTypeImpl( javaType.getJavaTypeClass(), new Type[0], null ), + typeConfiguration + ); + } } - @Override - public JdbcLiteralFormatter getJdbcLiteralFormatter(JavaType javaTypeDescriptor) { - final JavaType elementJavaType; + private static JavaType elementJavaType(JavaType javaTypeDescriptor) { if ( javaTypeDescriptor instanceof ByteArrayJavaType ) { // Special handling needed for Byte[], because that would conflict with the VARBINARY mapping - //noinspection unchecked - elementJavaType = (JavaType) ByteJavaType.INSTANCE; + return ByteJavaType.INSTANCE; } - else if ( javaTypeDescriptor instanceof BasicPluralJavaType ) { - //noinspection unchecked - elementJavaType = ((BasicPluralJavaType) javaTypeDescriptor).getElementJavaType(); + else if ( javaTypeDescriptor instanceof BasicPluralJavaType basicPluralJavaType ) { + return basicPluralJavaType.getElementJavaType(); } else { throw new IllegalArgumentException("not a BasicPluralJavaType"); } - return new JdbcLiteralFormatterArray<>( - javaTypeDescriptor, - elementJdbcType.getJdbcLiteralFormatter( elementJavaType ) - ); + } + + @Override + public JdbcLiteralFormatter getJdbcLiteralFormatter(JavaType javaTypeDescriptor) { + return new JdbcLiteralFormatterArray<>( javaTypeDescriptor, + elementJdbcType.getJdbcLiteralFormatter( elementJavaType( javaTypeDescriptor ) ) ); } @Override @@ -113,30 +111,18 @@ protected String getElementTypeName(JavaType javaType, SharedSessionContractI if ( elementJdbcType instanceof StructuredJdbcType structJdbcType ) { return structJdbcType.getStructTypeName(); } - final JavaType elementJavaType; - if ( javaType instanceof ByteArrayJavaType ) { - // Special handling needed for Byte[], because that would conflict with the VARBINARY mapping - elementJavaType = ByteJavaType.INSTANCE; - } - else { - elementJavaType = ( (BasicPluralJavaType) javaType ).getElementJavaType(); - } - final Size size = session.getJdbcServices() - .getDialect() - .getSizeStrategy() - .resolveSize( elementJdbcType, elementJavaType, null, null, null ); + final JavaType elementJavaType = elementJavaType( javaType ); + final Size size = + session.getJdbcServices().getDialect().getSizeStrategy() + .resolveSize( elementJdbcType, elementJavaType, null, null, null ); final DdlTypeRegistry ddlTypeRegistry = session.getTypeConfiguration().getDdlTypeRegistry(); - final String typeName = ddlTypeRegistry.getDescriptor( elementJdbcType.getDdlTypeCode() ) - .getTypeName( size, new BasicTypeImpl<>( elementJavaType, elementJdbcType), ddlTypeRegistry ); - int cutIndex = typeName.indexOf( '(' ); - if ( cutIndex > 0 ) { - // getTypeName for this case required length, etc, parameters. - // Cut them out and use database defaults. - return typeName.substring( 0, cutIndex ); - } - else { - return typeName; - } + final String typeName = + ddlTypeRegistry.getDescriptor( elementJdbcType.getDdlTypeCode() ) + .getTypeName( size, new BasicTypeImpl<>( elementJavaType, elementJdbcType), ddlTypeRegistry ); + // getTypeName for this case required length, etc, parameters. + // Cut them out and use database defaults. + final int cutIndex = typeName.indexOf( '(' ); + return cutIndex > 0 ? typeName.substring( 0, cutIndex ) : typeName; } protected Object[] getArray(BasicBinder binder, ValueBinder elementBinder, T value, WrapperOptions options) @@ -157,20 +143,23 @@ protected Object[] getArray(BasicBinder binder, ValueBinder elementBin else { final TypeConfiguration typeConfiguration = options.getTypeConfiguration(); final JdbcType underlyingJdbcType = - typeConfiguration.getJdbcTypeRegistry().getDescriptor( elementJdbcType.getDefaultSqlTypeCode() ); + typeConfiguration.getJdbcTypeRegistry() + .getDescriptor( elementJdbcType.getDefaultSqlTypeCode() ); final Class preferredJavaTypeClass = elementJdbcType.getPreferredJavaTypeClass( options ); final Class elementJdbcJavaTypeClass = preferredJavaTypeClass == null ? underlyingJdbcType.getJdbcRecommendedJavaTypeMapping(null, null, typeConfiguration ) .getJavaTypeClass() : preferredJavaTypeClass; - final Class arrayClass = (Class) - Array.newInstance( elementJdbcJavaTypeClass, 0 ).getClass(); + final var arrayClass = (Class) + newInstance( elementJdbcJavaTypeClass, 0 ).getClass(); return javaType.unwrap( value, arrayClass, options ); } } - protected X getArray(BasicExtractor extractor, java.sql.Array array, WrapperOptions options) throws SQLException { + protected X getArray(BasicExtractor extractor, java.sql.Array array, WrapperOptions options) + throws SQLException { + final JavaType javaType = extractor.getJavaType(); if ( array != null && getElementJdbcType() instanceof AggregateJdbcType aggregateJdbcType ) { final EmbeddableMappingType embeddableMappingType = aggregateJdbcType.getEmbeddableMappingType(); final Object rawArray = array.getArray(); @@ -187,10 +176,10 @@ protected X getArray(BasicExtractor extractor, java.sql.Array array, Wrap domainObjects[i] = instantiate( embeddableMappingType, attributeValues ); } } - return extractor.getJavaType().wrap( domainObjects, options ); + return javaType.wrap( domainObjects, options ); } else { - return extractor.getJavaType().wrap( array, options ); + return javaType.wrap( array, options ); } } @@ -209,9 +198,9 @@ protected void doBind(PreparedStatement st, X value, int index, WrapperOptions o @Override protected void doBind(CallableStatement st, X value, String name, WrapperOptions options) throws SQLException { - final java.sql.Array arr = getArray( value, options ); + final java.sql.Array array = getArray( value, options ); try { - st.setObject( name, arr, java.sql.Types.ARRAY ); + st.setObject( name, array, java.sql.Types.ARRAY ); } catch (SQLException ex) { throw new HibernateException( "JDBC driver does not support named parameters for setArray. Use positional.", ex ); @@ -262,20 +251,18 @@ public String getFriendlyName() { @Override public String toString() { - return "ArrayTypeDescriptor(" + getElementJdbcType().toString() + ")"; + return "ArrayTypeDescriptor(" + getElementJdbcType() + ")"; } /** - * Check equality. Needed so that ArrayJdbcType in collections correctly match each other. - * - * @param o other object + * Check equality. Needed so that {@code ArrayJdbcType} in collections correctly match each other. * @return true if the two array types share the same element type */ @Override - public boolean equals(Object o) { - return o != null - && getClass() == o.getClass() - && getElementJdbcType().equals( ( (ArrayJdbcType) o ).getElementJdbcType() ); + public boolean equals(Object that) { + return that instanceof ArrayJdbcType arrayJdbcType + && this.getClass() == that.getClass() + && getElementJdbcType().equals( arrayJdbcType.getElementJdbcType() ); } @Override diff --git a/hibernate-core/src/main/java/org/hibernate/type/internal/ConvertedBasicTypeImpl.java b/hibernate-core/src/main/java/org/hibernate/type/internal/ConvertedBasicTypeImpl.java index 6519468ddfae..e837e9d2d2c6 100644 --- a/hibernate-core/src/main/java/org/hibernate/type/internal/ConvertedBasicTypeImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/type/internal/ConvertedBasicTypeImpl.java @@ -318,11 +318,10 @@ public Object disassemble(Object value, SharedSessionContractImplementor session @Override @SuppressWarnings("unchecked") public final Object replace(Object original, Object target, SharedSessionContractImplementor session, Object owner, Map copyCache) { - if ( original == null && target == null ) { - return null; - } + return original == null && target == null + ? null + : converter.getDomainJavaType().getReplacement( (J) original, (J) target, session ); - return converter.getDomainJavaType().getReplacement( (J) original, (J) target, session ); } @Override