diff --git a/hibernate-core/src/main/java/org/hibernate/StatelessSession.java b/hibernate-core/src/main/java/org/hibernate/StatelessSession.java index 8a4a0ddacc87..31cd8c719a99 100644 --- a/hibernate-core/src/main/java/org/hibernate/StatelessSession.java +++ b/hibernate-core/src/main/java/org/hibernate/StatelessSession.java @@ -54,8 +54,8 @@ * Certain rules applying to stateful sessions are relaxed in a stateless * session: * diff --git a/hibernate-core/src/main/java/org/hibernate/boot/model/source/internal/hbm/ModelBinder.java b/hibernate-core/src/main/java/org/hibernate/boot/model/source/internal/hbm/ModelBinder.java index f1e247cb4f13..dc8f9fc46ba8 100644 --- a/hibernate-core/src/main/java/org/hibernate/boot/model/source/internal/hbm/ModelBinder.java +++ b/hibernate-core/src/main/java/org/hibernate/boot/model/source/internal/hbm/ModelBinder.java @@ -21,8 +21,6 @@ import org.hibernate.annotations.SourceType; import org.hibernate.boot.MappingException; import org.hibernate.boot.jaxb.Origin; -import org.hibernate.boot.jaxb.hbm.spi.JaxbHbmNamedNativeQueryType; -import org.hibernate.boot.jaxb.hbm.spi.JaxbHbmNamedQueryType; import org.hibernate.boot.model.source.spi.*; import org.hibernate.boot.model.IdentifierGeneratorDefinition; import org.hibernate.boot.model.TypeDefinition; @@ -40,7 +38,6 @@ import org.hibernate.boot.model.relational.Database; import org.hibernate.boot.model.relational.Namespace; import org.hibernate.boot.model.source.internal.ImplicitColumnNamingSecondPass; -import org.hibernate.boot.registry.classloading.spi.ClassLoaderService; import org.hibernate.boot.registry.classloading.spi.ClassLoadingException; import org.hibernate.boot.spi.BootstrapContext; import org.hibernate.boot.spi.InFlightMetadataCollector; @@ -51,14 +48,11 @@ import org.hibernate.cache.spi.access.AccessType; import org.hibernate.engine.FetchStyle; import org.hibernate.engine.FetchTiming; -import org.hibernate.engine.jdbc.env.spi.JdbcEnvironment; -import org.hibernate.engine.spi.FilterDefinition; import org.hibernate.generator.internal.GeneratedGeneration; import org.hibernate.generator.internal.SourceGeneration; import org.hibernate.internal.CoreLogging; import org.hibernate.internal.CoreMessageLogger; import org.hibernate.internal.util.StringHelper; -import org.hibernate.internal.util.collections.CollectionHelper; import org.hibernate.mapping.Any; import org.hibernate.mapping.Array; import org.hibernate.mapping.AttributeContainer; @@ -110,10 +104,14 @@ import static org.hibernate.boot.model.internal.GeneratorBinder.makeIdGenerator; import static org.hibernate.boot.model.naming.Identifier.toIdentifier; import static org.hibernate.boot.model.source.internal.hbm.Helper.reflectedPropertyClass; +import static org.hibernate.boot.model.source.internal.hbm.NamedQueryBinder.processNamedNativeQuery; +import static org.hibernate.boot.model.source.internal.hbm.NamedQueryBinder.processNamedQuery; import static org.hibernate.internal.log.DeprecationLogger.DEPRECATION_LOGGER; import static org.hibernate.internal.util.StringHelper.getNonEmptyOrConjunctionIfBothNonEmpty; import static org.hibernate.internal.util.StringHelper.isNotEmpty; +import static org.hibernate.internal.util.StringHelper.unqualify; import static org.hibernate.internal.util.collections.CollectionHelper.isEmpty; +import static org.hibernate.internal.util.collections.CollectionHelper.isNotEmpty; /** * Responsible for coordinating the binding of all information inside entity tags ({@code }, etc). @@ -144,9 +142,8 @@ public ModelBinder(final MetadataBuildingContext context) { public void bindEntityHierarchy(EntityHierarchySourceImpl hierarchySource) { final RootClass rootEntityDescriptor = new RootClass( hierarchySource.getRootEntityMappingDocument() ); bindRootEntity( hierarchySource, rootEntityDescriptor ); - hierarchySource.getRoot() - .getLocalMetadataBuildingContext() - .getMetadataCollector() + final RootEntitySourceImpl root = hierarchySource.getRoot(); + root.getLocalMetadataBuildingContext().getMetadataCollector() .addEntityBinding( rootEntityDescriptor ); switch ( hierarchySource.getHierarchyInheritanceType() ) { @@ -154,37 +151,36 @@ public void bindEntityHierarchy(EntityHierarchySourceImpl hierarchySource) { // nothing to do break; case DISCRIMINATED: - bindDiscriminatorSubclassEntities( hierarchySource.getRoot(), rootEntityDescriptor ); + bindDiscriminatorSubclassEntities( root, rootEntityDescriptor ); break; case JOINED: - bindJoinedSubclassEntities( hierarchySource.getRoot(), rootEntityDescriptor ); + bindJoinedSubclassEntities( root, rootEntityDescriptor ); break; case UNION: - bindUnionSubclassEntities( hierarchySource.getRoot(), rootEntityDescriptor ); + bindUnionSubclassEntities( root, rootEntityDescriptor ); break; } } private void bindRootEntity(EntityHierarchySourceImpl hierarchySource, RootClass rootEntityDescriptor) { - final MappingDocument mappingDocument = hierarchySource.getRoot().sourceMappingDocument(); + final RootEntitySourceImpl root = hierarchySource.getRoot(); + final MappingDocument mappingDocument = root.sourceMappingDocument(); - bindBasicEntityValues( - mappingDocument, - hierarchySource.getRoot(), - rootEntityDescriptor - ); + bindBasicEntityValues( mappingDocument, root, rootEntityDescriptor ); final Table primaryTable = bindEntityTableSpecification( mappingDocument, - hierarchySource.getRoot().getPrimaryTable(), + root.getPrimaryTable(), null, - hierarchySource.getRoot(), + root, rootEntityDescriptor ); rootEntityDescriptor.setTable( primaryTable ); if ( log.isTraceEnabled() ) { - log.tracef( "Mapping class: %s -> %s", rootEntityDescriptor.getEntityName(), primaryTable.getName() ); + log.tracef( "Mapping class: %s -> %s", + rootEntityDescriptor.getEntityName(), + primaryTable.getName() ); } rootEntityDescriptor.setOptimisticLockStyle( hierarchySource.getOptimisticLockStyle() ); @@ -195,26 +191,14 @@ private void bindRootEntity(EntityHierarchySourceImpl hierarchySource, RootClass DEPRECATION_LOGGER.warn( "Implicit/explicit polymorphism no longer supported" ); } - bindEntityIdentifier( - mappingDocument, - hierarchySource, - rootEntityDescriptor - ); + bindEntityIdentifier( mappingDocument, hierarchySource, rootEntityDescriptor ); if ( hierarchySource.getVersionAttributeSource() != null ) { - bindEntityVersion( - mappingDocument, - hierarchySource, - rootEntityDescriptor - ); + bindEntityVersion( mappingDocument, hierarchySource, rootEntityDescriptor ); } if ( hierarchySource.getDiscriminatorSource() != null ) { - bindEntityDiscriminator( - mappingDocument, - hierarchySource, - rootEntityDescriptor - ); + bindEntityDiscriminator( mappingDocument, hierarchySource, rootEntityDescriptor ); } applyCaching( mappingDocument, hierarchySource.getCaching(), rootEntityDescriptor ); @@ -225,16 +209,11 @@ private void bindRootEntity(EntityHierarchySourceImpl hierarchySource, RootClass // Primary key constraint rootEntityDescriptor.createPrimaryKey(); - bindAllEntityAttributes( - mappingDocument, - hierarchySource.getRoot(), - rootEntityDescriptor - ); + bindAllEntityAttributes( mappingDocument, root, rootEntityDescriptor ); - if ( hierarchySource.getNaturalIdCaching() != null ) { - if ( hierarchySource.getNaturalIdCaching().isRequested() ) { - rootEntityDescriptor.setNaturalIdCacheRegionName( hierarchySource.getNaturalIdCaching().getRegion() ); - } + final Caching naturalIdCaching = hierarchySource.getNaturalIdCaching(); + if ( naturalIdCaching != null && naturalIdCaching.isRequested() ) { + rootEntityDescriptor.setNaturalIdCacheRegionName( naturalIdCaching.getRegion() ); } } @@ -278,25 +257,13 @@ private void bindEntityIdentifier( RootClass rootEntityDescriptor) { switch ( hierarchySource.getIdentifierSource().getNature() ) { case SIMPLE: - bindSimpleEntityIdentifier( - mappingDocument, - hierarchySource, - rootEntityDescriptor - ); + bindSimpleEntityIdentifier( mappingDocument, hierarchySource, rootEntityDescriptor ); break; case AGGREGATED_COMPOSITE: - bindAggregatedCompositeEntityIdentifier( - mappingDocument, - hierarchySource, - rootEntityDescriptor - ); + bindAggregatedCompositeEntityIdentifier( mappingDocument, hierarchySource, rootEntityDescriptor ); break; case NON_AGGREGATED_COMPOSITE: - bindNonAggregatedCompositeEntityIdentifier( - mappingDocument, - hierarchySource, - rootEntityDescriptor - ); + bindNonAggregatedCompositeEntityIdentifier( mappingDocument, hierarchySource, rootEntityDescriptor ); break; default: throw new MappingException( @@ -315,49 +282,30 @@ private void bindBasicEntityValues( MappingDocument sourceDocument, AbstractEntitySourceImpl entitySource, PersistentClass entityDescriptor) { - entityDescriptor.setEntityName( entitySource.getEntityNamingSource().getEntityName() ); - entityDescriptor.setJpaEntityName( entitySource.getEntityNamingSource().getJpaEntityName() ); - entityDescriptor.setClassName( entitySource.getEntityNamingSource().getClassName() ); - if ( entityDescriptor.getJpaEntityName() != null && entityDescriptor.getClassName() != null ) { - metadataBuildingContext.getMetadataCollector() - .addImport( entityDescriptor.getJpaEntityName(), entityDescriptor.getClassName() ); + final var entityNamingSource = entitySource.getEntityNamingSource(); + final String entityName = entityNamingSource.getEntityName(); + + entityDescriptor.setEntityName( entityName ); + entityDescriptor.setJpaEntityName( entityNamingSource.getJpaEntityName() ); + entityDescriptor.setClassName( entityNamingSource.getClassName() ); + String jpaEntityName = entityDescriptor.getJpaEntityName(); + String className = entityDescriptor.getClassName(); + if ( jpaEntityName != null && className != null ) { + metadataBuildingContext.getMetadataCollector().addImport( jpaEntityName, className ); } + final String discriminatorMatchValue = entitySource.getDiscriminatorMatchValue(); entityDescriptor.setDiscriminatorValue( - entitySource.getDiscriminatorMatchValue() != null - ? entitySource.getDiscriminatorMatchValue() - : entityDescriptor.getEntityName() + discriminatorMatchValue == null + ? entityDescriptor.getEntityName() + : discriminatorMatchValue ); - // NOTE : entitySource#isLazy already accounts for MappingDefaults#areEntitiesImplicitlyLazy - if ( isNotEmpty( entitySource.getProxy() ) ) { - final String qualifiedProxyName = sourceDocument.qualifyClassName( entitySource.getProxy() ); - entityDescriptor.setProxyInterfaceName( qualifiedProxyName ); - entityDescriptor.setLazy( true ); - } - else if ( entitySource.isLazy() ) { - entityDescriptor.setProxyInterfaceName( entityDescriptor.getClassName() ); - entityDescriptor.setLazy( true ); - } - else { - entityDescriptor.setProxyInterfaceName( null ); - entityDescriptor.setLazy( false ); - } + setupProxying( sourceDocument, entitySource, entityDescriptor ); entityDescriptor.setAbstract( entitySource.isAbstract() ); - sourceDocument.getMetadataCollector().addImport( - entitySource.getEntityNamingSource().getEntityName(), - entitySource.getEntityNamingSource().getEntityName() - ); - - if ( sourceDocument.getEffectiveDefaults().isDefaultAutoImport() - && entitySource.getEntityNamingSource().getEntityName().indexOf( '.' ) > 0 ) { - sourceDocument.getMetadataCollector().addImport( - StringHelper.unqualify( entitySource.getEntityNamingSource().getEntityName() ), - entitySource.getEntityNamingSource().getEntityName() - ); - } + setupImports( sourceDocument, entityName ); entityDescriptor.setDynamicInsert( entitySource.isDynamicInsert() ); entityDescriptor.setDynamicUpdate( entitySource.isDynamicUpdate() ); @@ -366,61 +314,94 @@ else if ( entitySource.isLazy() ) { bindCustomSql( entitySource, entityDescriptor ); - final JdbcEnvironment jdbcEnvironment = sourceDocument.getMetadataCollector().getDatabase().getJdbcEnvironment(); - for ( String tableName : entitySource.getSynchronizedTableNames() ) { - final Identifier physicalTableName = sourceDocument.getBuildingOptions().getPhysicalNamingStrategy().toPhysicalTableName( - jdbcEnvironment.getIdentifierHelper().toIdentifier( tableName ), - jdbcEnvironment - ); - entityDescriptor.addSynchronizedTable( physicalTableName.render( jdbcEnvironment.getDialect() ) ); + entityDescriptor.addSynchronizedTable( physicalTableName( sourceDocument, tableName ) ); } for ( FilterSource filterSource : entitySource.getFilterSources() ) { - String condition = filterSource.getCondition(); - if ( condition == null ) { - final FilterDefinition filterDefinition = sourceDocument.getMetadataCollector().getFilterDefinition( filterSource.getName() ); - if ( filterDefinition != null ) { - condition = filterDefinition.getDefaultFilterCondition(); - } - } - entityDescriptor.addFilter( filterSource.getName(), - condition, + filterCondition( filterSource, sourceDocument ), filterSource.shouldAutoInjectAliases(), filterSource.getAliasToTableMap(), filterSource.getAliasToEntityMap() ); } - for ( JaxbHbmNamedQueryType namedQuery : entitySource.getNamedQueries() ) { - NamedQueryBinder.processNamedQuery( - sourceDocument, - namedQuery, - entitySource.getEntityNamingSource().getEntityName() + "." - ); + for ( var namedQuery : entitySource.getNamedQueries() ) { + processNamedQuery( sourceDocument, namedQuery, entityName + "." ); } - for ( JaxbHbmNamedNativeQueryType namedQuery : entitySource.getNamedNativeQueries() ) { - NamedQueryBinder.processNamedNativeQuery( - sourceDocument, - namedQuery, - entitySource.getEntityNamingSource().getEntityName() + "." - ); + for ( var namedQuery : entitySource.getNamedNativeQueries() ) { + processNamedNativeQuery( sourceDocument, namedQuery, entityName + "." ); } entityDescriptor.setMetaAttributes( entitySource.getToolingHintContext().getMetaAttributeMap() ); } + private static void setupImports(MappingDocument sourceDocument, String entityName) { + final var metadataCollector = sourceDocument.getMetadataCollector(); + metadataCollector.addImport( entityName, entityName ); + if ( sourceDocument.getEffectiveDefaults().isDefaultAutoImport() + && entityName.indexOf( '.' ) > 0 ) { + metadataCollector.addImport( unqualify( entityName ), entityName ); + } + } + + private static void setupProxying( + MappingDocument sourceDocument, + AbstractEntitySourceImpl entitySource, + PersistentClass entityDescriptor) { + // NOTE: entitySource#isLazy already accounts for MappingDefaults#areEntitiesImplicitlyLazy + if ( isNotEmpty( entitySource.getProxy() ) ) { + entityDescriptor.setProxyInterfaceName( sourceDocument.qualifyClassName( entitySource.getProxy() ) ); + entityDescriptor.setLazy( true ); + } + else if ( entitySource.isLazy() ) { + entityDescriptor.setProxyInterfaceName( entityDescriptor.getClassName() ); + entityDescriptor.setLazy( true ); + } + else { + entityDescriptor.setProxyInterfaceName( null ); + entityDescriptor.setLazy( false ); + } + } + + private static String filterCondition(FilterSource filterSource, MappingDocument sourceDocument) { + final String condition = filterSource.getCondition(); + if ( condition == null ) { + final var filterDefinition = + sourceDocument.getMetadataCollector() + .getFilterDefinition( filterSource.getName() ); + if ( filterDefinition != null ) { + return filterDefinition.getDefaultFilterCondition(); + } + else { + return null; + } + } + else { + return condition; + } + } + + private String physicalTableName(MappingDocument sourceDocument, String tableName) { + final var jdbcEnvironment = sourceDocument.getMetadataCollector().getDatabase().getJdbcEnvironment(); + return sourceDocument.getBuildingOptions().getPhysicalNamingStrategy() + .toPhysicalTableName( jdbcEnvironment.getIdentifierHelper().toIdentifier( tableName ), jdbcEnvironment ) + .render( jdbcEnvironment.getDialect() ); + } + private void bindDiscriminatorSubclassEntities( AbstractEntitySourceImpl entitySource, PersistentClass superEntityDescriptor) { for ( IdentifiableTypeSource subType : entitySource.getSubTypes() ) { - final SingleTableSubclass subEntityDescriptor = new SingleTableSubclass( superEntityDescriptor, metadataBuildingContext ); + final SingleTableSubclass subEntityDescriptor = + new SingleTableSubclass( superEntityDescriptor, metadataBuildingContext ); subEntityDescriptor.setCached( superEntityDescriptor.isCached() ); bindDiscriminatorSubclassEntity( (SubclassEntitySourceImpl) subType, subEntityDescriptor ); superEntityDescriptor.addSubclass( subEntityDescriptor ); - entitySource.getLocalMetadataBuildingContext().getMetadataCollector().addEntityBinding( subEntityDescriptor ); + entitySource.getLocalMetadataBuildingContext().getMetadataCollector() + .addEntityBinding( subEntityDescriptor ); } } @@ -428,45 +409,22 @@ private void bindDiscriminatorSubclassEntity( SubclassEntitySourceImpl entitySource, SingleTableSubclass entityDescriptor) { - bindBasicEntityValues( - entitySource.sourceMappingDocument(), - entitySource, - entityDescriptor - ); + final MappingDocument sourceDocument = entitySource.sourceMappingDocument(); + final var localMetadataCollector = entitySource.getLocalMetadataBuildingContext().getMetadataCollector(); - final String superEntityName = ( (EntitySource) entitySource.getSuperType() ).getEntityNamingSource() - .getEntityName(); - final EntityTableXref superEntityTableXref = entitySource.getLocalMetadataBuildingContext() - .getMetadataCollector() - .getEntityTableXref( superEntityName ); - if ( superEntityTableXref == null ) { - throw new MappingException( - String.format( - Locale.ENGLISH, - "Unable to locate entity table xref for entity [%s] super-type [%s]", - entityDescriptor.getEntityName(), - superEntityName - ), - entitySource.origin() - ); - } + bindBasicEntityValues( sourceDocument, entitySource, entityDescriptor ); + + final EntityTableXref superEntityTableXref = + superEntityTableXref( sourceDocument, entitySource, entityDescriptor, localMetadataCollector ); - entitySource.getLocalMetadataBuildingContext().getMetadataCollector().addEntityTableXref( + localMetadataCollector.addEntityTableXref( entitySource.getEntityNamingSource().getEntityName(), - database.toIdentifier( - entitySource.getLocalMetadataBuildingContext().getMetadataCollector().getLogicalTableName( - entityDescriptor.getTable() - ) - ), + database.toIdentifier( localMetadataCollector.getLogicalTableName( entityDescriptor.getTable() ) ), entityDescriptor.getTable(), superEntityTableXref ); - bindAllEntityAttributes( - entitySource.sourceMappingDocument(), - entitySource, - entityDescriptor - ); + bindAllEntityAttributes( sourceDocument, entitySource, entityDescriptor ); bindDiscriminatorSubclassEntities( entitySource, entityDescriptor ); } @@ -475,24 +433,22 @@ private void bindJoinedSubclassEntities( AbstractEntitySourceImpl entitySource, PersistentClass superEntityDescriptor) { for ( IdentifiableTypeSource subType : entitySource.getSubTypes() ) { - final JoinedSubclass subEntityDescriptor = new JoinedSubclass( superEntityDescriptor, metadataBuildingContext ); + final JoinedSubclass subEntityDescriptor = + new JoinedSubclass( superEntityDescriptor, metadataBuildingContext ); subEntityDescriptor.setCached( superEntityDescriptor.isCached() ); bindJoinedSubclassEntity( (JoinedSubclassEntitySourceImpl) subType, subEntityDescriptor ); superEntityDescriptor.addSubclass( subEntityDescriptor ); - entitySource.getLocalMetadataBuildingContext().getMetadataCollector().addEntityBinding( subEntityDescriptor ); + entitySource.getLocalMetadataBuildingContext().getMetadataCollector() + .addEntityBinding( subEntityDescriptor ); } } private void bindJoinedSubclassEntity( JoinedSubclassEntitySourceImpl entitySource, JoinedSubclass entityDescriptor) { - MappingDocument mappingDocument = entitySource.sourceMappingDocument(); + final MappingDocument mappingDocument = entitySource.sourceMappingDocument(); - bindBasicEntityValues( - mappingDocument, - entitySource, - entityDescriptor - ); + bindBasicEntityValues( mappingDocument, entitySource, entityDescriptor ); final Table primaryTable = bindEntityTableSpecification( mappingDocument, @@ -504,15 +460,14 @@ private void bindJoinedSubclassEntity( entityDescriptor.setTable( primaryTable ); if ( log.isTraceEnabled() ) { - log.tracef( "Mapping joined-subclass: %s -> %s", entityDescriptor.getEntityName(), primaryTable.getName() ); + log.tracef( "Mapping joined-subclass: %s -> %s", + entityDescriptor.getEntityName(), + primaryTable.getName() ); } // KEY - final DependantValue keyBinding = new DependantValue( - mappingDocument, - primaryTable, - entityDescriptor.getIdentifier() - ); + final DependantValue keyBinding = + new DependantValue( mappingDocument, primaryTable, entityDescriptor.getIdentifier() ); if ( mappingDocument.getBuildingOptions().useNationalizedCharacterData() ) { keyBinding.makeNationalized(); } @@ -540,11 +495,7 @@ public Identifier determineImplicitName(LocalMetadataBuildingContext context) { // todo : tooling hints - bindAllEntityAttributes( - entitySource.sourceMappingDocument(), - entitySource, - entityDescriptor - ); + bindAllEntityAttributes( mappingDocument, entitySource, entityDescriptor ); bindJoinedSubclassEntities( entitySource, entityDescriptor ); } @@ -552,24 +503,22 @@ private void bindUnionSubclassEntities( EntitySource entitySource, PersistentClass superEntityDescriptor) { for ( IdentifiableTypeSource subType : entitySource.getSubTypes() ) { - final UnionSubclass subEntityDescriptor = new UnionSubclass( superEntityDescriptor, metadataBuildingContext ); + final UnionSubclass subEntityDescriptor = + new UnionSubclass( superEntityDescriptor, metadataBuildingContext ); subEntityDescriptor.setCached( superEntityDescriptor.isCached() ); bindUnionSubclassEntity( (SubclassEntitySourceImpl) subType, subEntityDescriptor ); superEntityDescriptor.addSubclass( subEntityDescriptor ); - entitySource.getLocalMetadataBuildingContext().getMetadataCollector().addEntityBinding( subEntityDescriptor ); + entitySource.getLocalMetadataBuildingContext().getMetadataCollector() + .addEntityBinding( subEntityDescriptor ); } } private void bindUnionSubclassEntity( SubclassEntitySourceImpl entitySource, UnionSubclass entityDescriptor) { - MappingDocument mappingDocument = entitySource.sourceMappingDocument(); + final MappingDocument mappingDocument = entitySource.sourceMappingDocument(); - bindBasicEntityValues( - mappingDocument, - entitySource, - entityDescriptor - ); + bindBasicEntityValues( mappingDocument, entitySource, entityDescriptor ); final Table primaryTable = bindEntityTableSpecification( mappingDocument, @@ -581,7 +530,9 @@ private void bindUnionSubclassEntity( entityDescriptor.setTable( primaryTable ); if ( log.isTraceEnabled() ) { - log.tracef( "Mapping union-subclass: %s -> %s", entityDescriptor.getEntityName(), primaryTable.getName() ); + log.tracef( "Mapping union-subclass: %s -> %s", + entityDescriptor.getEntityName(), + primaryTable.getName() ); } // todo : tooling hints @@ -601,10 +552,7 @@ private void bindSimpleEntityIdentifier( RootClass rootEntityDescriptor) { final IdentifierSourceSimple idSource = (IdentifierSourceSimple) hierarchySource.getIdentifierSource(); - final BasicValue idValue = new BasicValue( - sourceDocument, - rootEntityDescriptor.getTable() - ); + final BasicValue idValue = new BasicValue( sourceDocument, rootEntityDescriptor.getTable() ); rootEntityDescriptor.setIdentifier( idValue ); bindSimpleValueType( @@ -655,15 +603,11 @@ public MetadataBuildingContext getBuildingContext() { ); if ( propertyName != null ) { - Property prop = new Property(); - prop.setValue( idValue ); - bindProperty( - sourceDocument, - idSource.getIdentifierAttributeSource(), - prop - ); - rootEntityDescriptor.setIdentifierProperty( prop ); - rootEntityDescriptor.setDeclaredIdentifierProperty( prop ); + final Property property = new Property(); + property.setValue( idValue ); + bindProperty( sourceDocument, idSource.getIdentifierAttributeSource(), property ); + rootEntityDescriptor.setIdentifierProperty( property ); + rootEntityDescriptor.setDeclaredIdentifierProperty( property ); } makeIdGenerator( @@ -685,8 +629,9 @@ private void bindAggregatedCompositeEntityIdentifier( // an aggregated composite-id is a composite-id that defines a singular // (composite) attribute as part of the entity to represent the id. - final IdentifierSourceAggregatedComposite identifierSource - = (IdentifierSourceAggregatedComposite) hierarchySource.getIdentifierSource(); + final var identifierSource = + (IdentifierSourceAggregatedComposite) + hierarchySource.getIdentifierSource(); final Component cid = new Component( mappingDocument, rootEntityDescriptor ); cid.setKey( true ); @@ -720,11 +665,8 @@ private void bindAggregatedCompositeEntityIdentifier( } private String extractIdClassName(IdentifierSourceAggregatedComposite identifierSource) { - if ( identifierSource.getEmbeddableSource().getTypeDescriptor() == null ) { - return null; - } - - return identifierSource.getEmbeddableSource().getTypeDescriptor().getName(); + final var typeDescriptor = identifierSource.getEmbeddableSource().getTypeDescriptor(); + return typeDescriptor == null ? null : typeDescriptor.getName(); } private static final String ID_MAPPER_PATH_PART = '<' + NavigablePath.IDENTIFIER_MAPPER_PROPERTY + '>'; @@ -733,8 +675,9 @@ private void bindNonAggregatedCompositeEntityIdentifier( MappingDocument mappingDocument, EntityHierarchySourceImpl hierarchySource, RootClass rootEntityDescriptor) { - final IdentifierSourceNonAggregatedComposite identifierSource - = (IdentifierSourceNonAggregatedComposite) hierarchySource.getIdentifierSource(); + final var identifierSource = + (IdentifierSourceNonAggregatedComposite) + hierarchySource.getIdentifierSource(); final Component cid = new Component( mappingDocument, rootEntityDescriptor ); cid.setKey( true ); @@ -742,13 +685,16 @@ private void bindNonAggregatedCompositeEntityIdentifier( final String idClassName = extractIdClassName( identifierSource ); + final AttributeRole attributeRoleBase = hierarchySource.getRoot().getAttributeRoleBase(); + + final String className = rootEntityDescriptor.getClassName(); bindComponent( mappingDocument, - hierarchySource.getRoot().getAttributeRoleBase().append( "" ).getFullPath(), + attributeRoleBase.append( "" ).getFullPath(), identifierSource.getEmbeddableSource(), cid, idClassName, - rootEntityDescriptor.getClassName(), + className, null, true, idClassName == null, @@ -756,16 +702,16 @@ private void bindNonAggregatedCompositeEntityIdentifier( ); if ( idClassName != null ) { - // we also need to bind the "id mapper". ugh, terrible name. Basically we need to - // create a virtual (embedded) composite for the non-aggregated attributes on the entity - // itself. + // We also need to bind the "id mapper". Ugh, terrible name. Basically, + // we need to create a virtual (embedded) composite for the non-aggregated + // attributes on the entity itself. final Component mapper = new Component( mappingDocument, rootEntityDescriptor ); bindComponent( mappingDocument, - hierarchySource.getRoot().getAttributeRoleBase().append( ID_MAPPER_PATH_PART ).getFullPath(), + attributeRoleBase.append( ID_MAPPER_PATH_PART ).getFullPath(), identifierSource.getEmbeddableSource(), mapper, - rootEntityDescriptor.getClassName(), + className, null, null, true, @@ -775,7 +721,7 @@ private void bindNonAggregatedCompositeEntityIdentifier( rootEntityDescriptor.setIdentifierMapper( mapper ); rootEntityDescriptor.setDeclaredIdentifierMapper( mapper ); - Property property = new Property(); + final Property property = new Property(); property.setName( NavigablePath.IDENTIFIER_MAPPER_PROPERTY ); property.setUpdateable( false ); property.setInsertable( false ); @@ -788,15 +734,14 @@ private void bindNonAggregatedCompositeEntityIdentifier( } private String extractIdClassName(IdentifierSourceNonAggregatedComposite identifierSource) { - if ( identifierSource.getIdClassSource() == null ) { + final var idClassSource = identifierSource.getIdClassSource(); + if ( idClassSource == null ) { return null; } - - if ( identifierSource.getIdClassSource().getTypeDescriptor() == null ) { - return null; + else { + final var typeDescriptor = idClassSource.getTypeDescriptor(); + return typeDescriptor == null ? null : typeDescriptor.getName(); } - - return identifierSource.getIdClassSource().getTypeDescriptor().getName(); } private void finishBindingCompositeIdentifier( @@ -818,15 +763,16 @@ private void finishBindingCompositeIdentifier( } } else { - Property prop = new Property(); - prop.setValue( cid ); + final Property property = new Property(); + property.setValue( cid ); bindProperty( sourceDocument, - ( (IdentifierSourceAggregatedComposite) identifierSource ).getIdentifierAttributeSource(), - prop + ( (IdentifierSourceAggregatedComposite) identifierSource ) + .getIdentifierAttributeSource(), + property ); - rootEntityDescriptor.setIdentifierProperty( prop ); - rootEntityDescriptor.setDeclaredIdentifierProperty( prop ); + rootEntityDescriptor.setIdentifierProperty( property ); + rootEntityDescriptor.setDeclaredIdentifierProperty( property ); } makeIdGenerator( @@ -841,20 +787,14 @@ private void bindEntityVersion( MappingDocument sourceDocument, EntityHierarchySourceImpl hierarchySource, RootClass rootEntityDescriptor) { - final VersionAttributeSource versionAttributeSource = hierarchySource.getVersionAttributeSource(); + final var versionAttributeSource = hierarchySource.getVersionAttributeSource(); - final BasicValue versionValue = new BasicValue( - sourceDocument, - rootEntityDescriptor.getTable() - ); + final BasicValue versionValue = + new BasicValue( sourceDocument, rootEntityDescriptor.getTable() ); versionValue.makeVersion(); - bindSimpleValueType( - sourceDocument, - versionAttributeSource.getTypeInformation(), - versionValue - ); + bindSimpleValueType( sourceDocument, versionAttributeSource.getTypeInformation(), versionValue ); relationalObjectBinder.bindColumnsAndFormulas( sourceDocument, @@ -864,16 +804,13 @@ private void bindEntityVersion( context -> implicitNamingStrategy.determineBasicColumnName( versionAttributeSource ) ); - Property property = new Property(); + final Property property = new Property(); property.setValue( versionValue ); - bindProperty( - sourceDocument, - versionAttributeSource, - property - ); + bindProperty( sourceDocument, versionAttributeSource, property ); - if ( versionAttributeSource.getUnsavedValue() != null ) { - versionValue.setNullValue( versionAttributeSource.getUnsavedValue() ); + final String unsavedValue = versionAttributeSource.getUnsavedValue(); + if ( unsavedValue != null ) { + versionValue.setNullValue( unsavedValue ); } else { versionValue.setNullValueUndefined(); @@ -892,39 +829,33 @@ private void bindEntityDiscriminator( MappingDocument sourceDocument, final EntityHierarchySourceImpl hierarchySource, RootClass rootEntityDescriptor) { - final BasicValue discriminatorValue = new BasicValue( - sourceDocument, - rootEntityDescriptor.getTable() - ); + final BasicValue discriminatorValue = + new BasicValue( sourceDocument, rootEntityDescriptor.getTable() ); rootEntityDescriptor.setDiscriminator( discriminatorValue ); - String typeName = hierarchySource.getDiscriminatorSource().getExplicitHibernateTypeName(); + final DiscriminatorSource discriminatorSource = hierarchySource.getDiscriminatorSource(); + + String typeName = discriminatorSource.getExplicitHibernateTypeName(); if ( typeName == null ) { typeName = "string"; } - bindSimpleValueType( - sourceDocument, - new HibernateTypeSourceImpl( typeName ), - discriminatorValue - ); + bindSimpleValueType( sourceDocument, new HibernateTypeSourceImpl( typeName ), discriminatorValue ); relationalObjectBinder.bindColumnOrFormula( sourceDocument, - hierarchySource.getDiscriminatorSource().getDiscriminatorRelationalValueSource(), + discriminatorSource.getDiscriminatorRelationalValueSource(), discriminatorValue, false, - context -> implicitNamingStrategy.determineDiscriminatorColumnName( - hierarchySource.getDiscriminatorSource() - ) + context -> implicitNamingStrategy.determineDiscriminatorColumnName( discriminatorSource ) ); rootEntityDescriptor.setPolymorphic( true ); - rootEntityDescriptor.setDiscriminatorInsertable( hierarchySource.getDiscriminatorSource().isInserted() ); + rootEntityDescriptor.setDiscriminatorInsertable( discriminatorSource.isInserted() ); // todo : currently isForced() is defined as boolean, not Boolean // although it has always been that way (DTD too) - final boolean force = hierarchySource.getDiscriminatorSource().isForced() - || sourceDocument.getBuildingOptions().shouldImplicitlyForceDiscriminatorInSelect(); + final boolean force = discriminatorSource.isForced() + || sourceDocument.getBuildingOptions().shouldImplicitlyForceDiscriminatorInSelect(); rootEntityDescriptor.setForceDiscriminator( force ); } @@ -932,9 +863,9 @@ private void bindAllEntityAttributes( MappingDocument mappingDocument, EntitySource entitySource, PersistentClass entityDescriptor) { - final EntityTableXref entityTableXref = mappingDocument.getMetadataCollector().getEntityTableXref( - entityDescriptor.getEntityName() - ); + final EntityTableXref entityTableXref = + mappingDocument.getMetadataCollector() + .getEntityTableXref( entityDescriptor.getEntityName() ); if ( entityTableXref == null ) { throw new AssertionFailure( String.format( @@ -947,26 +878,18 @@ private void bindAllEntityAttributes( } // make sure we bind secondary tables first! - for ( SecondaryTableSource secondaryTableSource : entitySource.getSecondaryTableMap().values() ) { + for ( var secondaryTableSource : entitySource.getSecondaryTableMap().values() ) { final Join secondaryTableJoin = new Join(); secondaryTableJoin.setPersistentClass( entityDescriptor ); - bindSecondaryTable( - mappingDocument, - secondaryTableSource, - secondaryTableJoin, - entityTableXref - ); + bindSecondaryTable( mappingDocument, secondaryTableSource, secondaryTableJoin, entityTableXref ); entityDescriptor.addJoin( secondaryTableJoin ); } for ( AttributeSource attributeSource : entitySource.attributeSources() ) { if ( attributeSource instanceof PluralAttributeSource pluralAttributeSource) { // plural attribute - final Property attribute = createPluralAttribute( - mappingDocument, - pluralAttributeSource, - entityDescriptor - ); + final Property attribute = + createPluralAttribute( mappingDocument, pluralAttributeSource, entityDescriptor ); attribute.setOptional( true ); entityDescriptor.addProperty( attribute ); } @@ -998,12 +921,8 @@ private void bindAllEntityAttributes( attributeContainer.addProperty( attribute ); - handleNaturalIdBinding( - mappingDocument, - entityDescriptor, - attribute, - basicAttributeSource.getNaturalIdMutability() - ); + handleNaturalIdBinding( mappingDocument, entityDescriptor, attribute, + basicAttributeSource.getNaturalIdMutability() ); } else if ( attributeSource instanceof SingularAttributeSourceEmbedded embeddedAttributeSource ) { final Identifier tableName = determineTable( mappingDocument, embeddedAttributeSource ); @@ -1030,12 +949,8 @@ else if ( attributeSource instanceof SingularAttributeSourceEmbedded embeddedAtt attributeContainer.addProperty( attribute ); - handleNaturalIdBinding( - mappingDocument, - entityDescriptor, - attribute, - embeddedAttributeSource.getNaturalIdMutability() - ); + handleNaturalIdBinding( mappingDocument, entityDescriptor, attribute, + embeddedAttributeSource.getNaturalIdMutability() ); } else if ( attributeSource instanceof SingularAttributeSourceManyToOne manyToOneAttributeSource ) { final Identifier tableName = @@ -1063,12 +978,8 @@ else if ( attributeSource instanceof SingularAttributeSourceManyToOne manyToOneA attributeContainer.addProperty( attribute ); - handleNaturalIdBinding( - mappingDocument, - entityDescriptor, - attribute, - manyToOneAttributeSource.getNaturalIdMutability() - ); + handleNaturalIdBinding( mappingDocument, entityDescriptor, attribute, + manyToOneAttributeSource.getNaturalIdMutability() ); } else if ( attributeSource instanceof SingularAttributeSourceOneToOne oneToOneAttributeSource ) { final Table table = entityDescriptor.getTable(); @@ -1083,12 +994,8 @@ else if ( attributeSource instanceof SingularAttributeSourceOneToOne oneToOneAtt entityDescriptor.addProperty( attribute ); - handleNaturalIdBinding( - mappingDocument, - entityDescriptor, - attribute, - oneToOneAttributeSource.getNaturalIdMutability() - ); + handleNaturalIdBinding( mappingDocument, entityDescriptor, attribute, + oneToOneAttributeSource.getNaturalIdMutability() ); } else if ( attributeSource instanceof SingularAttributeSourceAny anyAttributeSource ) { final Identifier tableName = determineTable( @@ -1119,12 +1026,8 @@ else if ( attributeSource instanceof SingularAttributeSourceAny anyAttributeSour attributeContainer.addProperty( attribute ); - handleNaturalIdBinding( - mappingDocument, - entityDescriptor, - attribute, - anyAttributeSource.getNaturalIdMutability() - ); + handleNaturalIdBinding( mappingDocument, entityDescriptor, attribute, + anyAttributeSource.getNaturalIdMutability() ); } } } @@ -1140,29 +1043,23 @@ private void handleNaturalIdBinding( PersistentClass entityBinding, Property attributeBinding, NaturalIdMutability naturalIdMutability) { - if ( naturalIdMutability == NaturalIdMutability.NOT_NATURAL_ID ) { - return; - } + if ( naturalIdMutability != NaturalIdMutability.NOT_NATURAL_ID ) { + attributeBinding.setNaturalIdentifier( true ); - attributeBinding.setNaturalIdentifier( true ); - - if ( naturalIdMutability == NaturalIdMutability.IMMUTABLE ) { - attributeBinding.setUpdateable( false ); - } + if ( naturalIdMutability == NaturalIdMutability.IMMUTABLE ) { + attributeBinding.setUpdateable( false ); + } - NaturalIdUniqueKeyBinder ukBinder = mappingDocument.getMetadataCollector().locateNaturalIdUniqueKeyBinder( - entityBinding.getEntityName() - ); + final var metadataCollector = mappingDocument.getMetadataCollector(); + final String entityName = entityBinding.getEntityName(); + NaturalIdUniqueKeyBinder ukBinder = metadataCollector.locateNaturalIdUniqueKeyBinder( entityName ); + if ( ukBinder == null ) { + ukBinder = new NaturalIdUniqueKeyBinderImpl( mappingDocument, entityBinding ); + metadataCollector.registerNaturalIdUniqueKeyBinder( entityName, ukBinder ); + } - if ( ukBinder == null ) { - ukBinder = new NaturalIdUniqueKeyBinderImpl( mappingDocument, entityBinding ); - mappingDocument.getMetadataCollector().registerNaturalIdUniqueKeyBinder( - entityBinding.getEntityName(), - ukBinder - ); + ukBinder.addAttributeBinding( attributeBinding ); } - - ukBinder.addAttributeBinding( attributeBinding ); } private Property createPluralAttribute( @@ -1172,7 +1069,7 @@ private Property createPluralAttribute( final Collection collectionBinding; if ( attributeSource instanceof PluralAttributeSourceListImpl pluralAttributeSourceList ) { - org.hibernate.mapping.List list = new org.hibernate.mapping.List(sourceDocument, entityDescriptor); + final var list = new org.hibernate.mapping.List(sourceDocument, entityDescriptor); collectionBinding = list; bindCollectionMetadata( sourceDocument, attributeSource, collectionBinding ); @@ -1191,7 +1088,7 @@ else if ( attributeSource instanceof PluralAttributeSourceSetImpl ) { ); } else if ( attributeSource instanceof PluralAttributeSourceMapImpl pluralAttributeSourceMap ) { - org.hibernate.mapping.Map map = new org.hibernate.mapping.Map( sourceDocument, entityDescriptor ); + final var map = new org.hibernate.mapping.Map( sourceDocument, entityDescriptor ); collectionBinding = map; bindCollectionMetadata( sourceDocument, attributeSource, collectionBinding ); @@ -1254,11 +1151,7 @@ else if ( attributeSource instanceof PluralAttributeSourcePrimitiveArrayImpl plu final Property attribute = new Property(); attribute.setValue( collectionBinding ); - bindProperty( - sourceDocument, - attributeSource, - attribute - ); + bindProperty( sourceDocument, attributeSource, attribute ); return attribute; } @@ -1284,7 +1177,8 @@ private void bindCollectionMetadata(MappingDocument mappingDocument, PluralAttri final Map typeParameters = new HashMap<>(); if ( typeName != null ) { // see if there is a corresponding type-def - final TypeDefinition typeDef = mappingDocument.getMetadataCollector().getTypeDefinition( typeName ); + final TypeDefinition typeDef = + mappingDocument.getMetadataCollector().getTypeDefinition( typeName ); if ( typeDef != null ) { typeName = typeDef.getTypeImplementorClass().getName(); if ( typeDef.getParameters() != null ) { @@ -1312,65 +1206,14 @@ private void bindCollectionMetadata(MappingDocument mappingDocument, PluralAttri binding.setLazy( false ); } - switch ( source.getFetchCharacteristics().getFetchStyle() ) { - case SELECT: { - binding.setFetchMode( FetchMode.SELECT ); - break; - } - case JOIN: { - binding.setFetchMode( FetchMode.JOIN ); - break; - } - case BATCH: { - binding.setFetchMode( FetchMode.SELECT ); - binding.setBatchSize( source.getFetchCharacteristics().getBatchSize() ); - break; - } - case SUBSELECT: { - binding.setFetchMode( FetchMode.SELECT ); - binding.setSubselectLoadable( true ); - // todo : this could totally be done using a "symbol map" approach - binding.getOwner().setSubselectLoadableCollections( true ); - break; - } - default: { - throw new AssertionFailure( "Unexpected FetchStyle : " + source.getFetchCharacteristics().getFetchStyle().name() ); - } - } + setupFetching( source, binding ); for ( String name : source.getSynchronizedTableNames() ) { binding.getSynchronizedTables().add( name ); } binding.setLoaderName( source.getCustomLoaderName() ); - if ( source.getCustomSqlInsert() != null ) { - binding.setCustomSQLInsert( - source.getCustomSqlInsert().sql(), - source.getCustomSqlInsert().callable(), - source.getCustomSqlInsert().checkStyle() - ); - } - if ( source.getCustomSqlUpdate() != null ) { - binding.setCustomSQLUpdate( - source.getCustomSqlUpdate().sql(), - source.getCustomSqlUpdate().callable(), - source.getCustomSqlUpdate().checkStyle() - ); - } - if ( source.getCustomSqlDelete() != null ) { - binding.setCustomSQLDelete( - source.getCustomSqlDelete().sql(), - source.getCustomSqlDelete().callable(), - source.getCustomSqlDelete().checkStyle() - ); - } - if ( source.getCustomSqlDeleteAll() != null ) { - binding.setCustomSQLDeleteAll( - source.getCustomSqlDeleteAll().sql(), - source.getCustomSqlDeleteAll().callable(), - source.getCustomSqlDeleteAll().checkStyle() - ); - } + bindCustomSql( source, binding ); if ( source instanceof Sortable sortable ) { if ( sortable.isSorted() ) { @@ -1396,17 +1239,9 @@ private void bindCollectionMetadata(MappingDocument mappingDocument, PluralAttri } for ( FilterSource filterSource : source.getFilterSources() ) { - String condition = filterSource.getCondition(); - if ( condition == null ) { - final FilterDefinition filterDefinition = mappingDocument.getMetadataCollector().getFilterDefinition( filterSource.getName() ); - if ( filterDefinition != null ) { - condition = filterDefinition.getDefaultFilterCondition(); - } - } - binding.addFilter( filterSource.getName(), - condition, + filterCondition( filterSource, mappingDocument ), filterSource.shouldAutoInjectAliases(), filterSource.getAliasToTableMap(), filterSource.getAliasToEntityMap() @@ -1414,6 +1249,61 @@ private void bindCollectionMetadata(MappingDocument mappingDocument, PluralAttri } } + private static void bindCustomSql(PluralAttributeSource source, Collection binding) { + if ( source.getCustomSqlInsert() != null ) { + binding.setCustomSQLInsert( + source.getCustomSqlInsert().sql(), + source.getCustomSqlInsert().callable(), + source.getCustomSqlInsert().checkStyle() + ); + } + if ( source.getCustomSqlUpdate() != null ) { + binding.setCustomSQLUpdate( + source.getCustomSqlUpdate().sql(), + source.getCustomSqlUpdate().callable(), + source.getCustomSqlUpdate().checkStyle() + ); + } + if ( source.getCustomSqlDelete() != null ) { + binding.setCustomSQLDelete( + source.getCustomSqlDelete().sql(), + source.getCustomSqlDelete().callable(), + source.getCustomSqlDelete().checkStyle() + ); + } + if ( source.getCustomSqlDeleteAll() != null ) { + binding.setCustomSQLDeleteAll( + source.getCustomSqlDeleteAll().sql(), + source.getCustomSqlDeleteAll().callable(), + source.getCustomSqlDeleteAll().checkStyle() + ); + } + } + + private static void setupFetching(PluralAttributeSource source, Collection binding) { + switch ( source.getFetchCharacteristics().getFetchStyle() ) { + case SELECT: + binding.setFetchMode( FetchMode.SELECT ); + break; + case JOIN: + binding.setFetchMode( FetchMode.JOIN ); + break; + case BATCH: + binding.setFetchMode( FetchMode.SELECT ); + binding.setBatchSize( source.getFetchCharacteristics().getBatchSize() ); + break; + case SUBSELECT: + binding.setFetchMode( FetchMode.SELECT ); + binding.setSubselectLoadable( true ); + // todo : this could totally be done using a "symbol map" approach + binding.getOwner().setSubselectLoadableCollections( true ); + break; + default: + throw new AssertionFailure( "Unexpected FetchStyle : " + + source.getFetchCharacteristics().getFetchStyle().name() ); + } + } + private void applyCaching(MappingDocument mappingDocument, Caching caching, Collection collection) { if ( isCacheEnabled( mappingDocument, caching ) ) { collection.setCacheConcurrencyStrategy( getConcurrencyStrategy( mappingDocument, caching ).getExternalName() ); @@ -1456,24 +1346,21 @@ else if ( attributeSource instanceof SingularAttributeSourceAny singularAttribut continue; } - if ( Objects.equals( tableName, determinedName ) ) { - continue; - } - - if ( tableName != null ) { - throw new MappingException( - String.format( - Locale.ENGLISH, - "Attribute [%s] referenced columns from multiple tables: %s, %s", - embeddedAttributeSource.getAttributeRole().getFullPath(), - tableName, - determinedName - ), - mappingDocument.getOrigin() - ); + if ( !Objects.equals( tableName, determinedName ) ) { + if ( tableName != null ) { + throw new MappingException( + String.format( + Locale.ENGLISH, + "Attribute [%s] referenced columns from multiple tables: %s, %s", + embeddedAttributeSource.getAttributeRole().getFullPath(), + tableName, + determinedName + ), + mappingDocument.getOrigin() + ); + } + tableName = determinedName; } - - tableName = determinedName; } return tableName; @@ -1487,24 +1374,22 @@ private Identifier determineTable( for ( RelationalValueSource relationalValueSource : relationalValueSources ) { // We need to get the containing table name for both columns and formulas, // particularly when a column/formula is for a property on a secondary table. - if ( Objects.equals( tableName, relationalValueSource.getContainingTableName() ) ) { - continue; - } + if ( !Objects.equals( tableName, relationalValueSource.getContainingTableName() ) ) { + if ( tableName != null ) { + throw new MappingException( + String.format( + Locale.ENGLISH, + "Attribute [%s] referenced columns from multiple tables: %s, %s", + attributeName, + tableName, + relationalValueSource.getContainingTableName() + ), + mappingDocument.getOrigin() + ); + } - if ( tableName != null ) { - throw new MappingException( - String.format( - Locale.ENGLISH, - "Attribute [%s] referenced columns from multiple tables: %s, %s", - attributeName, - tableName, - relationalValueSource.getContainingTableName() - ), - mappingDocument.getOrigin() - ); + tableName = relationalValueSource.getContainingTableName(); } - - tableName = relationalValueSource.getContainingTableName(); } return database.toIdentifier( tableName ); @@ -1566,11 +1451,8 @@ private void bindSecondaryTable( ); } - final DependantValue keyBinding = new DependantValue( - mappingDocument, - secondaryTable, - persistentClass.getIdentifier() - ); + final DependantValue keyBinding = + new DependantValue( mappingDocument, secondaryTable, persistentClass.getIdentifier() ); if ( mappingDocument.getBuildingOptions().useNationalizedCharacterData() ) { keyBinding.makeNationalized(); } @@ -1646,15 +1528,10 @@ private Property createEmbeddedAttribute( final Property attribute = new Property(); attribute.setValue( componentBinding ); - bindProperty( - sourceDocument, - embeddedSource, - attribute - ); + bindProperty( sourceDocument, embeddedSource, attribute ); if ( embeddedSource.isVirtualAttribute() ) { attribute.setPropertyAccessorName( "embedded" ); } - return attribute; } @@ -1665,11 +1542,7 @@ private Property createBasicAttribute( String containingClassName) { final String attributeName = attributeSource.getName(); - bindSimpleValueType( - sourceDocument, - attributeSource.getTypeInformation(), - value - ); + bindSimpleValueType( sourceDocument, attributeSource.getTypeInformation(), value ); relationalObjectBinder.bindColumnsAndFormulas( sourceDocument, @@ -1711,21 +1584,16 @@ private Property createBasicAttribute( value.createForeignKey(); - Property property = new Property(); + final Property property = new Property(); property.setValue( value ); property.setLob( value.isLob() ); - bindProperty( - sourceDocument, - attributeSource, - property - ); - + bindProperty( sourceDocument, attributeSource, property ); return property; } private void resolveLob(final SingularAttributeSourceBasic attributeSource, SimpleValue value) { // Resolves whether the property is LOB based on the type attribute on the attribute property source. - // Essentially this expects the type to map to a CLOB/NCLOB/BLOB sql type internally and compares. + // Essentially, this expects the type to map to a CLOB/NCLOB/BLOB SQL type internally and compares. if ( !value.isLob() && value.getTypeName() != null ) { final String typeName = value.getTypeName(); final MetadataBuildingContext context = attributeSource.getBuildingContext(); @@ -1745,7 +1613,7 @@ private void resolveLob(final SingularAttributeSourceBasic attributeSource, Simp // If the prior check didn't set the lob flag, this will inspect the column sql-type attribute value and // if this maps to CLOB/NCLOB/BLOB then the value will be marked as lob. if ( !value.isLob() ) { - for ( RelationalValueSource relationalValueSource : attributeSource.getRelationalValueSources() ) { + for ( var relationalValueSource : attributeSource.getRelationalValueSources() ) { if ( relationalValueSource instanceof ColumnSource columnSource ) { if ( isLob( null, columnSource.getSqlType() ) ) { value.makeLob(); @@ -1811,7 +1679,8 @@ private void handlePropertyReference( String referencedEntityName, String referencedPropertyName, String sourceElementSynopsis) { - PersistentClass entityBinding = mappingDocument.getMetadataCollector().getEntityBinding( referencedEntityName ); + final PersistentClass entityBinding = + mappingDocument.getMetadataCollector().getEntityBinding( referencedEntityName ); if ( entityBinding == null ) { // entity may just not have been processed yet - set up a delayed handler registerDelayedPropertyReferenceHandler( @@ -1826,7 +1695,8 @@ private void handlePropertyReference( ); } else { - Property propertyBinding = entityBinding.getReferencedProperty( referencedPropertyName ); + final Property propertyBinding = + entityBinding.getReferencedProperty( referencedPropertyName ); if ( propertyBinding == null ) { // attribute may just not have been processed yet - set up a delayed handler registerDelayedPropertyReferenceHandler( @@ -1896,17 +1766,19 @@ public void bindOneToOne( oneToOneBinding.setForeignKeyType( ForeignKeyDirection.TO_PARENT ); } - oneToOneBinding.setLazy( oneToOneSource.getFetchCharacteristics().getFetchTiming() == FetchTiming.DELAYED ); + final var fetchCharacteristics = oneToOneSource.getFetchCharacteristics(); + oneToOneBinding.setLazy( fetchCharacteristics.getFetchTiming() == FetchTiming.DELAYED ); oneToOneBinding.setFetchMode( - oneToOneSource.getFetchCharacteristics().getFetchStyle() == FetchStyle.SELECT + fetchCharacteristics.getFetchStyle() == FetchStyle.SELECT ? FetchMode.SELECT : FetchMode.JOIN ); - oneToOneBinding.setUnwrapProxy( oneToOneSource.getFetchCharacteristics().isUnwrapProxies() ); + oneToOneBinding.setUnwrapProxy( fetchCharacteristics.isUnwrapProxies() ); - if ( isNotEmpty( oneToOneSource.getReferencedEntityAttributeName() ) ) { - oneToOneBinding.setReferencedPropertyName( oneToOneSource.getReferencedEntityAttributeName() ); + final String referencedEntityAttributeName = oneToOneSource.getReferencedEntityAttributeName(); + if ( isNotEmpty( referencedEntityAttributeName ) ) { + oneToOneBinding.setReferencedPropertyName( referencedEntityAttributeName ); oneToOneBinding.setReferenceToPrimaryKey( false ); } else { @@ -1934,12 +1806,14 @@ private Property createManyToOneAttribute( String containingClassName) { final String attributeName = manyToOneSource.getName(); + final String explicitReferencedEntityName = manyToOneSource.getReferencedEntityName(); final String referencedEntityName; - if ( manyToOneSource.getReferencedEntityName() != null ) { - referencedEntityName = manyToOneSource.getReferencedEntityName(); + if ( explicitReferencedEntityName != null ) { + referencedEntityName = explicitReferencedEntityName; } else { - Class reflectedPropertyClass = reflectedPropertyClass( sourceDocument, containingClassName, attributeName ); + final Class reflectedPropertyClass = + reflectedPropertyClass( sourceDocument, containingClassName, attributeName ); if ( reflectedPropertyClass != null ) { referencedEntityName = reflectedPropertyClass.getName(); } @@ -1962,7 +1836,6 @@ private Property createManyToOneAttribute( bindManyToOneAttribute( sourceDocument, manyToOneSource, manyToOneBinding, referencedEntityName ); final String propertyRef = manyToOneBinding.getReferencedPropertyName(); - if ( propertyRef != null ) { handlePropertyReference( sourceDocument, @@ -1972,13 +1845,9 @@ private Property createManyToOneAttribute( ); } - Property prop = new Property(); - prop.setValue( manyToOneBinding ); - bindProperty( - sourceDocument, - manyToOneSource, - prop - ); + final Property property = new Property(); + property.setValue( manyToOneBinding ); + bindProperty( sourceDocument, manyToOneSource, property ); if ( isNotEmpty( manyToOneSource.getCascadeStyleName() ) ) { // todo : would be better to delay this the end of binding (second pass, etc) @@ -2006,7 +1875,7 @@ private Property createManyToOneAttribute( } } - return prop; + return property; } private void bindManyToOneAttribute( @@ -2014,21 +1883,23 @@ private void bindManyToOneAttribute( final SingularAttributeSourceManyToOne manyToOneSource, ManyToOne manyToOneBinding, String referencedEntityName) { - // NOTE : no type information to bind + // NOTE: no type information to bind manyToOneBinding.setReferencedEntityName( referencedEntityName ); - if ( isNotEmpty( manyToOneSource.getReferencedEntityAttributeName() ) ) { - manyToOneBinding.setReferencedPropertyName( manyToOneSource.getReferencedEntityAttributeName() ); + final String referencedEntityAttributeName = manyToOneSource.getReferencedEntityAttributeName(); + if ( isNotEmpty( referencedEntityAttributeName ) ) { + manyToOneBinding.setReferencedPropertyName( referencedEntityAttributeName ); manyToOneBinding.setReferenceToPrimaryKey( false ); } else { manyToOneBinding.setReferenceToPrimaryKey( true ); } - manyToOneBinding.setLazy( manyToOneSource.getFetchCharacteristics().getFetchTiming() == FetchTiming.DELAYED ); - manyToOneBinding.setUnwrapProxy( manyToOneSource.getFetchCharacteristics().isUnwrapProxies() ); + final var fetchCharacteristics = manyToOneSource.getFetchCharacteristics(); + manyToOneBinding.setLazy( fetchCharacteristics.getFetchTiming() == FetchTiming.DELAYED ); + manyToOneBinding.setUnwrapProxy( fetchCharacteristics.isUnwrapProxies() ); manyToOneBinding.setFetchMode( - manyToOneSource.getFetchCharacteristics().getFetchStyle() == FetchStyle.SELECT + fetchCharacteristics.getFetchStyle() == FetchStyle.SELECT ? FetchMode.SELECT : FetchMode.JOIN ); @@ -2092,11 +1963,12 @@ private Property createAnyAssociationAttribute( SingularAttributeSourceAny anyMapping, Any anyBinding, String entityName) { - final String attributeName = anyMapping.getName(); - bindAny( sourceDocument, anyMapping, anyBinding, anyMapping.getAttributeRole() ); + final AttributeRole role = anyMapping.getAttributeRole(); + + bindAny( sourceDocument, anyMapping, anyBinding, role ); - prepareValueTypeViaReflection( sourceDocument, anyBinding, entityName, attributeName, anyMapping.getAttributeRole() ); + prepareValueTypeViaReflection( sourceDocument, anyBinding, entityName, anyMapping.getName(), role ); anyBinding.createForeignKey(); @@ -2114,18 +1986,14 @@ private void bindAny( anyBinding.setLazy( anyMapping.isLazy() ); - final TypeResolution keyTypeResolution = resolveType( - sourceDocument, - anyMapping.getKeySource().getTypeSource() - ); + final TypeResolution keyTypeResolution = + resolveType( sourceDocument, anyMapping.getKeySource().getTypeSource() ); if ( keyTypeResolution != null ) { anyBinding.setIdentifierType( keyTypeResolution.typeName ); } - final TypeResolution discriminatorTypeResolution = resolveType( - sourceDocument, - anyMapping.getDiscriminatorSource().getTypeSource() - ); + final TypeResolution discriminatorTypeResolution = + resolveType( sourceDocument, anyMapping.getDiscriminatorSource().getTypeSource() ); final String discriminatorTypeName; final BasicType discriminatorType; @@ -2139,8 +2007,10 @@ private void bindAny( } else { discriminatorTypeName = StandardBasicTypes.STRING.getName(); - discriminatorType = metadataBuildingContext.getBootstrapContext().getTypeConfiguration().getBasicTypeRegistry() - .resolve( StandardBasicTypes.STRING ); + discriminatorType = + metadataBuildingContext.getBootstrapContext() + .getTypeConfiguration().getBasicTypeRegistry() + .resolve( StandardBasicTypes.STRING ); } anyBinding.setMetaType( discriminatorTypeName ); @@ -2150,10 +2020,12 @@ private void bindAny( anyMapping.getDiscriminatorSource().getValueMappings().forEach( (discriminatorValueString, entityName) -> { try { - final Object discriminatorValue = discriminatorType.getJavaTypeDescriptor().fromString( discriminatorValueString ); + final Object discriminatorValue = + discriminatorType.getJavaTypeDescriptor() + .fromString( discriminatorValueString ); discriminatorValueToEntityNameMap.put( discriminatorValue, entityName ); } - catch (Exception e) { + catch (Exception exception) { throw new MappingException( String.format( Locale.ENGLISH, @@ -2162,7 +2034,7 @@ private void bindAny( entityName, attributeRole.getFullPath() ), - e, + exception, sourceDocument.getOrigin() ); } @@ -2200,14 +2072,16 @@ private BasicType resolveExplicitlyNamedAnyDiscriminatorType( if ( isEmpty( parameters ) ) { // can use a standard one - final BasicType basicTypeByName = typeConfiguration.getBasicTypeRegistry().getRegisteredType( typeName ); + final BasicType basicTypeByName = + typeConfiguration.getBasicTypeRegistry().getRegisteredType( typeName ); if ( basicTypeByName != null ) { return basicTypeByName; } } // see if it is a named TypeDefinition - final TypeDefinition typeDefinition = metadataBuildingContext.getTypeDefinitionRegistry().resolve( typeName ); + final TypeDefinition typeDefinition = + metadataBuildingContext.getTypeDefinitionRegistry().resolve( typeName ); if ( typeDefinition != null ) { final BasicValue.Resolution resolution = typeDefinition.resolve( parameters, @@ -2223,7 +2097,7 @@ private BasicType resolveExplicitlyNamedAnyDiscriminatorType( return resolution.getLegacyResolvedBasicType(); } else { - final ClassLoaderService classLoaderService = bootstrapContext.getClassLoaderService(); + final var classLoaderService = bootstrapContext.getClassLoaderService(); try { final Object typeInstance = typeInstance( typeName, classLoaderService.classForName( typeName ) ); @@ -2327,13 +2201,10 @@ private void bindProperty( if ( propertySource.isSingular() ) { final SingularAttributeSource singularAttributeSource = (SingularAttributeSource) propertySource; - property.setInsertable( singularAttributeSource.isInsertable() ); property.setUpdateable( singularAttributeSource.isUpdatable() ); - - // NOTE : Property#is refers to whether a property is lazy via bytecode enhancement (not proxies) + // NOTE: Property#is refers to whether a property is lazy via bytecode enhancement (not proxies) property.setLazy( singularAttributeSource.isBytecodeLazy() ); - handleGenerationTiming( mappingDocument, propertySource, property, singularAttributeSource.getGenerationTiming() ); } @@ -2345,22 +2216,23 @@ private void bindProperty( } private String toCascadeString(EnumSet defaultCascadeTypes) { - if ( CollectionHelper.isEmpty( defaultCascadeTypes ) ) { + if ( isEmpty( defaultCascadeTypes ) ) { return "none"; } - - boolean firstPass = true; - final StringBuilder buffer = new StringBuilder(); - for ( CascadeType cascadeType : defaultCascadeTypes ) { - if ( firstPass ) { - firstPass = false; - } - else { - buffer.append( ", " ); + else { + boolean firstPass = true; + final StringBuilder buffer = new StringBuilder(); + for ( var cascadeType : defaultCascadeTypes ) { + if ( firstPass ) { + firstPass = false; + } + else { + buffer.append( ", " ); + } + buffer.append( cascadeType.name().toLowerCase( Locale.ROOT ) ); } - buffer.append( cascadeType.name().toLowerCase( Locale.ROOT ) ); + return buffer.toString(); } - return buffer.toString(); } private static void handleGenerationTiming( @@ -2412,15 +2284,12 @@ private void bindComponent( String containingClassName, String propertyName, boolean isVirtual) { - final String fullRole = embeddableSource.getAttributeRoleBase().getFullPath(); - final String explicitComponentClassName = extractExplicitComponentClassName( embeddableSource ); - bindComponent( sourceDocument, - fullRole, + embeddableSource.getAttributeRoleBase().getFullPath(), embeddableSource, component, - explicitComponentClassName, + extractExplicitComponentClassName( embeddableSource ), containingClassName, propertyName, isVirtual, @@ -2430,11 +2299,8 @@ private void bindComponent( } private String extractExplicitComponentClassName(EmbeddableSource embeddableSource) { - if ( embeddableSource.getTypeDescriptor() == null ) { - return null; - } - - return embeddableSource.getTypeDescriptor().getName(); + final var typeDescriptor = embeddableSource.getTypeDescriptor(); + return typeDescriptor == null ? null : typeDescriptor.getName(); } private void bindComponent( @@ -2477,22 +2343,18 @@ else if ( isVirtual ) { log.tracef( "Binding component [%s]", role ); if ( isNotEmpty( explicitComponentClassName ) ) { try { - final Class componentClass = sourceDocument.getBootstrapContext() - .getClassLoaderAccess() - .classForName( explicitComponentClassName ); + final Class componentClass = + sourceDocument.getBootstrapContext().getClassLoaderAccess() + .classForName( explicitComponentClassName ); if ( CompositeUserType.class.isAssignableFrom( componentClass ) ) { + @SuppressWarnings("unchecked") // Safe, we just chacked + final var compositeTypeClass = + (Class>) + componentClass; componentBinding.setTypeName( explicitComponentClassName ); - CompositeUserType compositeUserType; - if ( !sourceDocument.getBuildingOptions().isAllowExtensionsInCdi() ) { - compositeUserType = (CompositeUserType) FallbackBeanInstanceProducer.INSTANCE.produceBeanInstance( componentClass ); - } - else { - compositeUserType = (CompositeUserType) sourceDocument.getBootstrapContext() - .getManagedBeanRegistry() - .getBean( componentClass ) - .getBeanInstance(); - } - explicitComponentClassName = compositeUserType.embeddable().getName(); + explicitComponentClassName = + compositeUserType( sourceDocument, compositeTypeClass ) + .embeddable().getName(); } } catch (ClassLoadingException ex) { @@ -2503,13 +2365,10 @@ else if ( isVirtual ) { } else if ( componentBinding.getOwner().hasPojoRepresentation() ) { log.tracef( "Attempting to determine component class by reflection %s", role ); - final Class reflectedComponentClass; - if ( isNotEmpty( containingClassName ) && isNotEmpty( propertyName ) ) { - reflectedComponentClass = reflectedPropertyClass( sourceDocument, containingClassName, propertyName ); - } - else { - reflectedComponentClass = null; - } + final Class reflectedComponentClass = + isNotEmpty( containingClassName ) && isNotEmpty( propertyName ) + ? reflectedPropertyClass( sourceDocument, containingClassName, propertyName ) + : null; if ( reflectedComponentClass == null ) { log.debugf( @@ -2530,8 +2389,9 @@ else if ( componentBinding.getOwner().hasPojoRepresentation() ) { // todo : anything else to pass along? bindAllCompositeAttributes( sourceDocument, embeddableSource, componentBinding ); - if ( embeddableSource.getParentReferenceAttributeName() != null ) { - componentBinding.setParentProperty( embeddableSource.getParentReferenceAttributeName() ); + final String parentReferenceAttributeName = embeddableSource.getParentReferenceAttributeName(); + if ( parentReferenceAttributeName != null ) { + componentBinding.setParentProperty( parentReferenceAttributeName ); } if ( embeddableSource.isUnique() ) { @@ -2546,6 +2406,15 @@ else if ( componentBinding.getOwner().hasPojoRepresentation() ) { } } + private static CompositeUserType compositeUserType( + MappingDocument sourceDocument, + Class> componentClass) { + return sourceDocument.getBuildingOptions().isAllowExtensionsInCdi() + ? sourceDocument.getBootstrapContext().getManagedBeanRegistry() + .getBean( componentClass ).getBeanInstance() + : FallbackBeanInstanceProducer.INSTANCE.produceBeanInstance( componentClass ); + } + private void bindAllCompositeAttributes( MappingDocument sourceDocument, EmbeddableSource embeddableSource, @@ -2628,21 +2497,19 @@ private static void bindSimpleValueType( } final TypeResolution typeResolution = resolveType( mappingDocument, typeSource ); - if ( typeResolution == null ) { - // no explicit type info was found - return; - } - - if ( CollectionHelper.isNotEmpty( typeResolution.parameters ) ) { - simpleValue.setTypeParameters( typeResolution.parameters ); - if ( simpleValue instanceof BasicValue basicValue ) { - basicValue.setExplicitTypeParams( typeResolution.parameters ); + if ( typeResolution != null ) { + if ( isNotEmpty( typeResolution.parameters ) ) { + simpleValue.setTypeParameters( typeResolution.parameters ); + if ( simpleValue instanceof BasicValue basicValue ) { + basicValue.setExplicitTypeParams( typeResolution.parameters ); + } } - } - if ( typeResolution.typeName != null ) { - simpleValue.setTypeName( typeResolution.typeName ); + if ( typeResolution.typeName != null ) { + simpleValue.setTypeName( typeResolution.typeName ); + } } + // otherwise no explicit type info was found } private static class TypeResolution { @@ -2662,10 +2529,15 @@ private static TypeResolution resolveType( return null; } - String typeName = typeSource.getName(); - final TypeDefinition typeDefinition = sourceDocument.getMetadataCollector().getTypeDefinition( typeName ); + final TypeDefinition typeDefinition = + sourceDocument.getMetadataCollector() + .getTypeDefinition( typeSource.getName() ); final Map typeParameters = new HashMap<>(); - if ( typeDefinition != null ) { + final String typeName; + if ( typeDefinition == null ) { + typeName = typeSource.getName(); + } + else { // the explicit name referred to a type-def typeName = typeDefinition.getTypeImplementorClass().getName(); if ( typeDefinition.getParameters() != null ) { @@ -2674,8 +2546,9 @@ private static TypeResolution resolveType( } // parameters on the property mapping should override parameters in the type-def - if ( typeSource.getParameters() != null ) { - typeParameters.putAll( typeSource.getParameters() ); + final var parameters = typeSource.getParameters(); + if ( parameters != null ) { + typeParameters.putAll( parameters ); } return new TypeResolution( typeName, typeParameters ); @@ -2692,6 +2565,7 @@ private Table bindEntityTableSpecification( determineSchemaName( tableSpecSource ) ); + final String contributorName = mappingDocument.getCurrentContributorName(); final boolean isTable = tableSpecSource instanceof TableSource; final boolean isAbstract = entityDescriptor.isAbstract() != null && entityDescriptor.isAbstract(); final String subselect; @@ -2715,16 +2589,16 @@ public MetadataBuildingContext getBuildingContext() { return mappingDocument; } }; - logicalTableName = mappingDocument.getBuildingOptions() - .getImplicitNamingStrategy() - .determinePrimaryTableName( implicitNamingSource ); + logicalTableName = + mappingDocument.getBuildingOptions().getImplicitNamingStrategy() + .determinePrimaryTableName( implicitNamingSource ); } if ( denormalizedSuperTable == null ) { table = namespace.createTable( logicalTableName, (identifier) -> new Table( - mappingDocument.getCurrentContributorName(), + contributorName, namespace, identifier, isAbstract @@ -2735,7 +2609,7 @@ public MetadataBuildingContext getBuildingContext() { table = namespace.createDenormalizedTable( logicalTableName, (physicalTableName) -> new DenormalizedTable( - mappingDocument.getCurrentContributorName(), + contributorName, namespace, physicalTableName, isAbstract, @@ -2749,11 +2623,11 @@ public MetadataBuildingContext getBuildingContext() { subselect = inLineViewSource.getSelectStatement(); logicalTableName = database.toIdentifier( inLineViewSource.getLogicalName() ); if ( denormalizedSuperTable == null ) { - table = new Table( mappingDocument.getCurrentContributorName(), namespace, subselect, isAbstract ); + table = new Table( contributorName, namespace, subselect, isAbstract ); } else { table = new DenormalizedTable( - mappingDocument.getCurrentContributorName(), + contributorName, namespace, subselect, isAbstract, @@ -2763,30 +2637,13 @@ public MetadataBuildingContext getBuildingContext() { table.setName( logicalTableName.render() ); } - EntityTableXref superEntityTableXref = null; - - if ( entitySource.getSuperType() != null ) { - final String superEntityName = ( (EntitySource) entitySource.getSuperType() ).getEntityNamingSource() - .getEntityName(); - superEntityTableXref = mappingDocument.getMetadataCollector().getEntityTableXref( superEntityName ); - if ( superEntityTableXref == null ) { - throw new MappingException( - String.format( - Locale.ENGLISH, - "Unable to locate entity table xref for entity [%s] super-type [%s]", - entityDescriptor.getEntityName(), - superEntityName - ), - mappingDocument.getOrigin() - ); - } - } + final var metadataCollector = mappingDocument.getMetadataCollector(); - mappingDocument.getMetadataCollector().addEntityTableXref( + metadataCollector.addEntityTableXref( entitySource.getEntityNamingSource().getEntityName(), logicalTableName, table, - superEntityTableXref + superEntityTableXref( mappingDocument, entitySource, entityDescriptor, metadataCollector ) ); if ( isTable ) { @@ -2799,27 +2656,48 @@ public MetadataBuildingContext getBuildingContext() { table.setComment(tableSpecSource.getComment()); - mappingDocument.getMetadataCollector().addTableNameBinding( logicalTableName, table ); + metadataCollector.addTableNameBinding( logicalTableName, table ); return table; } - private Identifier determineCatalogName(TableSpecificationSource tableSpecSource) { - if ( isNotEmpty( tableSpecSource.getExplicitCatalogName() ) ) { - return database.toIdentifier( tableSpecSource.getExplicitCatalogName() ); + private static EntityTableXref superEntityTableXref( + MappingDocument mappingDocument, + EntitySource entitySource, + PersistentClass entityDescriptor, + InFlightMetadataCollector metadataCollector) { + if ( entitySource.getSuperType() != null ) { + final EntitySource supertype = (EntitySource) entitySource.getSuperType(); + final String superEntityName = supertype.getEntityNamingSource().getEntityName(); + final EntityTableXref superEntityTableXref = metadataCollector.getEntityTableXref( superEntityName ); + if ( superEntityTableXref == null ) { + throw new MappingException( + String.format( + Locale.ENGLISH, + "Unable to locate entity table xref for entity [%s] super-type [%s]", + entityDescriptor.getEntityName(), + superEntityName + ), + mappingDocument.getOrigin() + ); + } + return superEntityTableXref; } else { return null; } } + private Identifier determineCatalogName(TableSpecificationSource tableSpecSource) { + return isNotEmpty( tableSpecSource.getExplicitCatalogName() ) + ? database.toIdentifier( tableSpecSource.getExplicitCatalogName() ) + : null; + } + private Identifier determineSchemaName(TableSpecificationSource tableSpecSource) { - if ( isNotEmpty( tableSpecSource.getExplicitSchemaName() ) ) { - return database.toIdentifier( tableSpecSource.getExplicitSchemaName() ); - } - else { - return null; - } + return isNotEmpty( tableSpecSource.getExplicitSchemaName() ) + ? database.toIdentifier( tableSpecSource.getExplicitSchemaName() ) + : null; } private static void bindCustomSql( @@ -2886,7 +2764,8 @@ private void registerSecondPass(SecondPass secondPass, MetadataBuildingContext c - public static final class DelayedPropertyReferenceHandlerImpl implements InFlightMetadataCollector.DelayedPropertyReferenceHandler { + public static final class DelayedPropertyReferenceHandlerImpl + implements InFlightMetadataCollector.DelayedPropertyReferenceHandler { public final String referencedEntityName; public final String referencedPropertyName; public final boolean isUnique; @@ -2974,7 +2853,7 @@ public Collection getCollectionBinding() { } @Override - public void doSecondPass(Map persistentClasses) throws org.hibernate.MappingException { + public void doSecondPass(Map persistentClasses) { bindCollectionTable(); bindCollectionKey(); @@ -2987,17 +2866,18 @@ public void doSecondPass(Map persistentClasses) throws collectionBinding.createAllKeys(); if ( log.isTraceEnabled() ) { + final Collection collectionBinding = getCollectionBinding(); log.tracef( "Mapped collection: %s", getPluralAttributeSource().getAttributeRole().getFullPath() ); - log.tracef( " + table -> %s", getCollectionBinding().getTable().getName() ); - log.tracef( " + key -> %s", columns( getCollectionBinding().getKey() ) ); - if ( getCollectionBinding().isIndexed() ) { - log.tracef( " + index -> %s", columns( ( (IndexedCollection) getCollectionBinding() ).getIndex() ) ); + log.tracef( " + table -> %s", collectionBinding.getTable().getName() ); + log.tracef( " + key -> %s", columns( collectionBinding.getKey() ) ); + if ( collectionBinding.isIndexed() ) { + log.tracef( " + index -> %s", columns( ( (IndexedCollection) collectionBinding).getIndex() ) ); } - if ( getCollectionBinding().isOneToMany() ) { - log.tracef( " + one-to-many -> %s", ( (OneToMany) getCollectionBinding().getElement() ).getReferencedEntityName() ); + if ( collectionBinding.isOneToMany() ) { + log.tracef( " + one-to-many -> %s", ( (OneToMany) collectionBinding.getElement() ).getReferencedEntityName() ); } else { - log.tracef( " + element -> %s", columns( getCollectionBinding().getElement() ) ); + log.tracef( " + element -> %s", columns( collectionBinding.getElement() ) ); } } } @@ -3007,13 +2887,12 @@ private void bindCollectionTable() { // 1) one-to-many // 2) everything else - if ( pluralAttributeSource.getElementSource() instanceof PluralAttributeElementSourceOneToMany elementSource ) { + if ( pluralAttributeSource.getElementSource() + instanceof PluralAttributeElementSourceOneToMany elementSource ) { // For one-to-many mappings, the "collection table" is the same as the table // of the associated entity (the entity making up the collection elements). // So lookup the associated entity and use its table here - - final PersistentClass persistentClass = getReferencedEntityBinding( elementSource.getReferencedEntityName() ); - + final var persistentClass = getReferencedEntityBinding( elementSource.getReferencedEntityName() ); // even though defines a property-ref I do not see where legacy // code ever attempts to use that to "adjust" the table in its use to // the actual table the referenced property belongs to. @@ -3021,57 +2900,16 @@ private void bindCollectionTable() { collectionBinding.setCollectionTable( persistentClass.getTable() ); } else { - final TableSpecificationSource tableSpecSource = pluralAttributeSource.getCollectionTableSpecificationSource(); + final var tableSpecSource = pluralAttributeSource.getCollectionTableSpecificationSource(); final Identifier logicalCatalogName = determineCatalogName( tableSpecSource ); final Identifier logicalSchemaName = determineSchemaName( tableSpecSource ); final Namespace namespace = database.locateNamespace( logicalCatalogName, logicalSchemaName ); final Table collectionTable; - if ( tableSpecSource instanceof TableSource tableSource ) { - Identifier logicalName; - - if ( isNotEmpty( tableSource.getExplicitTableName() ) ) { - logicalName = toIdentifier( - tableSource.getExplicitTableName(), - mappingDocument.getEffectiveDefaults().isDefaultQuoteIdentifiers() - ); - } - else { - final EntityNaming ownerEntityNaming = new EntityNamingSourceImpl( - collectionBinding.getOwner().getEntityName(), - collectionBinding.getOwner().getClassName(), - collectionBinding.getOwner().getJpaEntityName() - ); - final ImplicitCollectionTableNameSource implicitNamingSource = new ImplicitCollectionTableNameSource() { - @Override - public Identifier getOwningPhysicalTableName() { - return collectionBinding.getOwner().getTable().getNameIdentifier(); - } - - @Override - public EntityNaming getOwningEntityNaming() { - return ownerEntityNaming; - } - - @Override - public AttributePath getOwningAttributePath() { - return pluralAttributeSource.getAttributePath(); - } - - @Override - public MetadataBuildingContext getBuildingContext() { - return mappingDocument; - } - }; - logicalName = mappingDocument.getBuildingOptions() - .getImplicitNamingStrategy() - .determineCollectionTableName( implicitNamingSource ); - } - collectionTable = namespace.createTable( - logicalName, - (identifier) -> new Table( + logicalName( tableSource ), + identifier -> new Table( metadataBuildingContext.getCurrentContributorName(), namespace, identifier, @@ -3092,17 +2930,58 @@ public MetadataBuildingContext getBuildingContext() { } + final Table collectionTable = collectionBinding.getCollectionTable(); + if ( log.isTraceEnabled() ) { log.tracef( "Mapping collection: %s -> %s", collectionBinding.getRole(), - collectionBinding.getCollectionTable().getName() ); + collectionTable.getName() ); } if ( pluralAttributeSource.getCollectionTableComment() != null ) { - collectionBinding.getCollectionTable().setComment( pluralAttributeSource.getCollectionTableComment() ); + collectionTable.setComment( pluralAttributeSource.getCollectionTableComment() ); } if ( pluralAttributeSource.getCollectionTableCheck() != null ) { - collectionBinding.getCollectionTable().addCheckConstraint( pluralAttributeSource.getCollectionTableCheck() ); + collectionTable.addCheckConstraint( pluralAttributeSource.getCollectionTableCheck() ); + } + } + + private Identifier logicalName(TableSource tableSource) { + if ( isNotEmpty( tableSource.getExplicitTableName() ) ) { + return toIdentifier( tableSource.getExplicitTableName(), + mappingDocument.getEffectiveDefaults().isDefaultQuoteIdentifiers() ); + } + else { + final PersistentClass owner = collectionBinding.getOwner(); + final EntityNaming ownerEntityNaming = new EntityNamingSourceImpl( + owner.getEntityName(), + owner.getClassName(), + owner.getJpaEntityName() + ); + final ImplicitCollectionTableNameSource implicitNamingSource = + new ImplicitCollectionTableNameSource() { + @Override + public Identifier getOwningPhysicalTableName() { + return owner.getTable().getNameIdentifier(); + } + + @Override + public EntityNaming getOwningEntityNaming() { + return ownerEntityNaming; + } + + @Override + public AttributePath getOwningAttributePath() { + return pluralAttributeSource.getAttributePath(); + } + + @Override + public MetadataBuildingContext getBuildingContext() { + return mappingDocument; + } + }; + return mappingDocument.getBuildingOptions().getImplicitNamingStrategy() + .determineCollectionTableName( implicitNamingSource ); } } @@ -3111,7 +2990,8 @@ protected void createBackReferences() { && !collectionBinding.isInverse() && !collectionBinding.getKey().isNullable() ) { // for non-inverse one-to-many, with a not-null fk, add a backref! - final String entityName = ( (OneToMany) collectionBinding.getElement() ).getReferencedEntityName(); + final OneToMany oneToMany = (OneToMany) collectionBinding.getElement(); + final String entityName = oneToMany.getReferencedEntityName(); final PersistentClass referenced = getReferencedEntityBinding( entityName ); final Backref backref = new Backref(); backref.setName( '_' + collectionBinding.getOwnerEntityName() + "." + pluralAttributeSource.getName() + "Backref" ); @@ -3134,21 +3014,23 @@ protected void createBackReferences() { } protected void bindCollectionKey() { - final PluralAttributeKeySource keySource = getPluralAttributeSource().getKeySource(); + final PluralAttributeSource pluralAttributeSource = getPluralAttributeSource(); + final PluralAttributeKeySource keySource = pluralAttributeSource.getKeySource(); final String referencedPropertyName = keySource.getReferencedPropertyName(); - getCollectionBinding().setReferencedPropertyName( referencedPropertyName ); + final Collection collectionBinding = getCollectionBinding(); + collectionBinding.setReferencedPropertyName( referencedPropertyName ); - final PersistentClass owner = getCollectionBinding().getOwner(); + final PersistentClass owner = collectionBinding.getOwner(); final KeyValue keyVal = referencedPropertyName == null ? owner.getIdentifier() : (KeyValue) owner.getRecursiveProperty( referencedPropertyName ).getValue(); final DependantValue key = new DependantValue( mappingDocument, - getCollectionBinding().getCollectionTable(), + collectionBinding.getCollectionTable(), keyVal ); setForeignKeyName( key, keySource.getExplicitForeignKeyName() ); - key.setOnDeleteAction( getOnDeleteAction( getPluralAttributeSource().getKeySource().isCascadeDeleteEnabled() ) ); + key.setOnDeleteAction( getOnDeleteAction( pluralAttributeSource.getKeySource().isCascadeDeleteEnabled() ) ); // final ImplicitJoinColumnNameSource.Nature implicitNamingNature; // if ( getPluralAttributeSource().getElementSource() instanceof PluralAttributeElementSourceManyToMany @@ -3161,18 +3043,19 @@ protected void bindCollectionKey() { relationalObjectBinder.bindColumnsAndFormulas( mappingDocument, - getPluralAttributeSource().getKeySource().getRelationalValueSources(), + keySource.getRelationalValueSources(), key, - getPluralAttributeSource().getKeySource().areValuesNullableByDefault(), - context -> context.getMetadataCollector().getDatabase().toIdentifier( Collection.DEFAULT_KEY_COLUMN_NAME ) + keySource.areValuesNullableByDefault(), + context -> context.getMetadataCollector().getDatabase() + .toIdentifier( Collection.DEFAULT_KEY_COLUMN_NAME ) ); key.sortProperties(); key.createForeignKey(); - getCollectionBinding().setKey( key ); + collectionBinding.setKey( key ); - key.setNullable( getPluralAttributeSource().getKeySource().areValuesNullableByDefault() ); - key.setUpdateable( getPluralAttributeSource().getKeySource().areValuesIncludedInUpdateByDefault() ); + key.setNullable( keySource.areValuesNullableByDefault() ); + key.setUpdateable( keySource.areValuesIncludedInUpdateByDefault() ); } protected void bindCollectionIdentifier() { @@ -3221,41 +3104,39 @@ protected void bindCollectionElement() { getPluralAttributeSource().getNature() ); } + final Collection collectionBinding = getCollectionBinding(); + final MappingDocument mappingDocument = getMappingDocument(); if ( pluralElementSource instanceof PluralAttributeElementSourceBasic elementSource ) { - final BasicValue elementBinding = new BasicValue( - getMappingDocument(), - getCollectionBinding().getCollectionTable() - ); + final BasicValue elementBinding = + new BasicValue( mappingDocument, collectionBinding.getCollectionTable() ); bindSimpleValueType( - getMappingDocument(), + mappingDocument, elementSource.getExplicitHibernateTypeSource(), elementBinding ); relationalObjectBinder.bindColumnsAndFormulas( - mappingDocument, + this.mappingDocument, elementSource.getRelationalValueSources(), elementBinding, elementSource.areValuesNullableByDefault(), - context -> context.getMetadataCollector().getDatabase().toIdentifier( Collection.DEFAULT_ELEMENT_COLUMN_NAME ) + context -> context.getMetadataCollector().getDatabase() + .toIdentifier( Collection.DEFAULT_ELEMENT_COLUMN_NAME ) ); - getCollectionBinding().setElement( elementBinding ); + collectionBinding.setElement( elementBinding ); // Collection#setWhere is used to set the "where" clause that applies to the collection table // (the table containing the basic elements) // This "where" clause comes from the collection mapping; e.g., - getCollectionBinding().setWhere( getPluralAttributeSource().getWhere() ); + collectionBinding.setWhere( getPluralAttributeSource().getWhere() ); } else if ( pluralElementSource instanceof PluralAttributeElementSourceEmbedded elementSource ) { - final Component elementBinding = new Component( - getMappingDocument(), - getCollectionBinding() - ); + final Component elementBinding = new Component( mappingDocument, collectionBinding ); final EmbeddableSource embeddableSource = elementSource.getEmbeddableSource(); bindComponent( - mappingDocument, + this.mappingDocument, embeddableSource, elementBinding, null, @@ -3263,23 +3144,21 @@ else if ( pluralElementSource instanceof PluralAttributeElementSourceEmbedded el false ); - getCollectionBinding().setElement( elementBinding ); + collectionBinding.setElement( elementBinding ); // Collection#setWhere is used to set the "where" clause that applies to the collection table // (the table containing the embeddable elements) // This "where" clause comes from the collection mapping; e.g., - getCollectionBinding().setWhere( getPluralAttributeSource().getWhere() ); + collectionBinding.setWhere( getPluralAttributeSource().getWhere() ); } else if ( pluralElementSource instanceof PluralAttributeElementSourceOneToMany elementSource ) { - final OneToMany elementBinding = new OneToMany( - getMappingDocument(), - getCollectionBinding().getOwner() - ); - collectionBinding.setElement( elementBinding ); + final OneToMany elementBinding = + new OneToMany( mappingDocument, collectionBinding.getOwner() ); + this.collectionBinding.setElement( elementBinding ); final PersistentClass referencedEntityBinding = getReferencedEntityBinding( elementSource.getReferencedEntityName() ); - collectionBinding.setWhere( + this.collectionBinding.setWhere( getNonEmptyOrConjunctionIfBothNonEmpty( referencedEntityBinding.getWhere(), getPluralAttributeSource().getWhere() @@ -3291,13 +3170,11 @@ else if ( pluralElementSource instanceof PluralAttributeElementSourceOneToMany e elementBinding.setIgnoreNotFound( elementSource.isIgnoreNotFound() ); } else if ( pluralElementSource instanceof PluralAttributeElementSourceManyToMany elementSource ) { - final ManyToOne elementBinding = new ManyToOne( - getMappingDocument(), - getCollectionBinding().getCollectionTable() - ); + final ManyToOne elementBinding = + new ManyToOne( mappingDocument, collectionBinding.getCollectionTable() ); relationalObjectBinder.bindColumnsAndFormulas( - getMappingDocument(), + mappingDocument, elementSource.getRelationalValueSources(), elementBinding, false, @@ -3305,49 +3182,49 @@ else if ( pluralElementSource instanceof PluralAttributeElementSourceManyToMany .toIdentifier( Collection.DEFAULT_ELEMENT_COLUMN_NAME ) ); - elementBinding.setLazy( - elementSource.getFetchCharacteristics() - .getFetchTiming() != FetchTiming.IMMEDIATE - ); + final var fetchCharacteristics = elementSource.getFetchCharacteristics(); + elementBinding.setLazy( fetchCharacteristics.getFetchTiming() != FetchTiming.IMMEDIATE ); elementBinding.setFetchMode( - elementSource.getFetchCharacteristics().getFetchStyle() == FetchStyle.SELECT + fetchCharacteristics.getFetchStyle() == FetchStyle.SELECT ? FetchMode.SELECT : FetchMode.JOIN ); setForeignKeyName( elementBinding, elementSource.getExplicitForeignKeyName() ); - elementBinding.setReferencedEntityName( elementSource.getReferencedEntityName() ); - if ( isNotEmpty( elementSource.getReferencedEntityAttributeName() ) ) { - elementBinding.setReferencedPropertyName( elementSource.getReferencedEntityAttributeName() ); + final String referencedEntityName = elementSource.getReferencedEntityName(); + elementBinding.setReferencedEntityName( referencedEntityName ); + final String referencedEntityAttributeName = elementSource.getReferencedEntityAttributeName(); + if ( isNotEmpty( referencedEntityAttributeName ) ) { + elementBinding.setReferencedPropertyName( referencedEntityAttributeName ); elementBinding.setReferenceToPrimaryKey( false ); } else { elementBinding.setReferenceToPrimaryKey( true ); } - getCollectionBinding().setElement( elementBinding ); + collectionBinding.setElement( elementBinding ); - final PersistentClass referencedEntityBinding = getReferencedEntityBinding( elementSource.getReferencedEntityName() ); + final PersistentClass referencedEntityBinding = getReferencedEntityBinding( referencedEntityName ); // Collection#setWhere is used to set the "where" clause that applies to the collection table // (which is the join table for a many-to-many association). // This "where" clause comes from the collection mapping; e.g., - getCollectionBinding().setWhere( getPluralAttributeSource().getWhere() ); + collectionBinding.setWhere( getPluralAttributeSource().getWhere() ); - getCollectionBinding().setManyToManyWhere( + collectionBinding.setManyToManyWhere( getNonEmptyOrConjunctionIfBothNonEmpty( referencedEntityBinding.getWhere(), elementSource.getWhere() ) ); - getCollectionBinding().setManyToManyOrdering( elementSource.getOrder() ); + collectionBinding.setManyToManyOrdering( elementSource.getOrder() ); - if ( ! CollectionHelper.isEmpty( elementSource.getFilterSources() ) + if ( !isEmpty( elementSource.getFilterSources() ) || elementSource.getWhere() != null ) { - if ( getCollectionBinding().getFetchMode() == FetchMode.JOIN - && elementBinding.getFetchMode() != FetchMode.JOIN ) { + if ( collectionBinding.getFetchMode() == FetchMode.JOIN + && elementBinding.getFetchMode() != FetchMode.JOIN ) { throw new MappingException( String.format( Locale.ENGLISH, @@ -3355,7 +3232,7 @@ else if ( pluralElementSource instanceof PluralAttributeElementSourceManyToMany "valid within collection [%s] using join fetching", getPluralAttributeSource().getAttributeRole().getFullPath() ), - getMappingDocument().getOrigin() + mappingDocument.getOrigin() ); } } @@ -3379,7 +3256,7 @@ else if ( pluralElementSource instanceof PluralAttributeElementSourceManyToMany filterSource.getName(), getPluralAttributeSource().getAttributeRole().getFullPath() ), - getMappingDocument().getOrigin() + mappingDocument.getOrigin() ); } @@ -3392,7 +3269,7 @@ else if ( pluralElementSource instanceof PluralAttributeElementSourceManyToMany ); } - getCollectionBinding().addManyToManyFilter( + collectionBinding.addManyToManyFilter( filterSource.getName(), filterSource.getCondition(), filterSource.shouldAutoInjectAliases(), @@ -3402,18 +3279,18 @@ else if ( pluralElementSource instanceof PluralAttributeElementSourceManyToMany } } else if ( pluralElementSource instanceof PluralAttributeElementSourceManyToAny elementSource ) { - final Any elementBinding = new Any( getMappingDocument(), getCollectionBinding().getCollectionTable() ); + final Any elementBinding = new Any( mappingDocument, collectionBinding.getCollectionTable() ); bindAny( - mappingDocument, + this.mappingDocument, elementSource, elementBinding, getPluralAttributeSource().getAttributeRole().append( "element" ) ); - getCollectionBinding().setElement( elementBinding ); + collectionBinding.setElement( elementBinding ); // Collection#setWhere is used to set the "where" clause that applies to the collection table // (which is the join table for a many-to-any association). // This "where" clause comes from the collection mapping; e.g., - getCollectionBinding().setWhere( getPluralAttributeSource().getWhere() ); + collectionBinding.setWhere( getPluralAttributeSource().getWhere() ); } } @@ -3465,7 +3342,6 @@ protected void bindCollectionIndex() { @Override protected void createBackReferences() { super.createBackReferences(); - createIndexBackRef( getMappingDocument(), getPluralAttributeSource(), @@ -3514,28 +3390,31 @@ protected void bindCollectionIndex() { protected void createBackReferences() { super.createBackReferences(); + final var collectionBinding = getCollectionBinding(); + boolean indexIsFormula = false; - for ( Selectable selectable: getCollectionBinding().getIndex().getSelectables() ) { + for ( Selectable selectable: collectionBinding.getIndex().getSelectables() ) { if ( selectable.isFormula() ) { indexIsFormula = true; break; } } - if ( getCollectionBinding().isOneToMany() - && !getCollectionBinding().getKey().isNullable() - && !getCollectionBinding().isInverse() + if ( collectionBinding.isOneToMany() + && !collectionBinding.getKey().isNullable() + && !collectionBinding.isInverse() && !indexIsFormula ) { - final String entityName = ( (OneToMany) getCollectionBinding().getElement() ).getReferencedEntityName(); + final OneToMany oneToMany = (OneToMany) collectionBinding.getElement(); + final String entityName = oneToMany.getReferencedEntityName(); final PersistentClass referenced = getMappingDocument().getMetadataCollector().getEntityBinding( entityName ); final IndexBackref backref = new IndexBackref(); - backref.setName( '_' + getCollectionBinding().getOwnerEntityName() + "." + getPluralAttributeSource().getName() + "IndexBackref" ); + backref.setName( '_' + collectionBinding.getOwnerEntityName() + "." + getPluralAttributeSource().getName() + "IndexBackref" ); backref.setOptional( true ); backref.setUpdateable( false ); backref.setSelectable( false ); - backref.setCollectionRole( getCollectionBinding().getRole() ); - backref.setEntityName( getCollectionBinding().getOwner().getEntityName() ); - backref.setValue( getCollectionBinding().getIndex() ); + backref.setCollectionRole( collectionBinding.getRole() ); + backref.setEntityName( collectionBinding.getOwner().getEntityName() ); + backref.setValue( collectionBinding.getIndex() ); referenced.addProperty( backref ); } } @@ -3589,7 +3468,6 @@ protected void bindCollectionIndex() { @Override protected void createBackReferences() { super.createBackReferences(); - createIndexBackRef( getMappingDocument(), getPluralAttributeSource(), @@ -3605,7 +3483,8 @@ private void createIndexBackRef( if ( collectionBinding.isOneToMany() && !collectionBinding.getKey().isNullable() && !collectionBinding.isInverse() ) { - final String entityName = ( (OneToMany) collectionBinding.getElement() ).getReferencedEntityName(); + OneToMany oneToMany = (OneToMany) collectionBinding.getElement(); + final String entityName = oneToMany.getReferencedEntityName(); final PersistentClass referenced = mappingDocument.getMetadataCollector().getEntityBinding( entityName ); final IndexBackref backref = new IndexBackref(); backref.setName( '_' + collectionBinding.getOwnerEntityName() + "." + pluralAttributeSource.getName() + "IndexBackref" ); @@ -3663,15 +3542,10 @@ public void bindListOrArrayIndex( final IndexedPluralAttributeSource attributeSource, org.hibernate.mapping.List collectionBinding) { final PluralAttributeSequentialIndexSource indexSource = - (PluralAttributeSequentialIndexSource) attributeSource.getIndexSource(); - + (PluralAttributeSequentialIndexSource) + attributeSource.getIndexSource(); final BasicValue indexBinding = new BasicValue( mappingDocument, collectionBinding.getCollectionTable() ); - - bindSimpleValueType( - mappingDocument, - indexSource.getTypeInformation(), - indexBinding - ); + bindSimpleValueType( mappingDocument, indexSource.getTypeInformation(), indexBinding ); relationalObjectBinder.bindColumnsAndFormulas( mappingDocument, @@ -3704,11 +3578,7 @@ private void bindMapKey( final PluralAttributeIndexSource indexSource = pluralAttributeSource.getIndexSource(); if ( indexSource instanceof PluralAttributeMapKeySourceBasic mapKeySource ) { final BasicValue value = new BasicValue( mappingDocument, collectionBinding.getCollectionTable() ); - bindSimpleValueType( - mappingDocument, - mapKeySource.getTypeInformation(), - value - ); + bindSimpleValueType( mappingDocument, mapKeySource.getTypeInformation(), value ); if ( !value.isTypeSpecified() ) { throw new MappingException( "map index element must specify a type: " @@ -3767,12 +3637,8 @@ public MetadataBuildingContext getBuildingContext() { } else if ( indexSource instanceof PluralAttributeMapKeyManyToAnySource mapKeySource) { final Any mapKeyBinding = new Any( mappingDocument, collectionBinding.getCollectionTable() ); - bindAny( - mappingDocument, - mapKeySource, - mapKeyBinding, - pluralAttributeSource.getAttributeRole().append( "key" ) - ); + bindAny( mappingDocument, mapKeySource, mapKeyBinding, + pluralAttributeSource.getAttributeRole().append( "key" ) ); collectionBinding.setIndex( mapKeyBinding ); } } @@ -3797,7 +3663,7 @@ public ManyToOneColumnBinder( this.referencedEntityName = referencedEntityName; boolean allNamed = true; - for ( RelationalValueSource relationalValueSource : manyToOneSource.getRelationalValueSources() ) { + for ( var relationalValueSource : manyToOneSource.getRelationalValueSources() ) { if ( relationalValueSource instanceof ColumnSource columnSource ) { if ( columnSource.getName() == null ) { allNamed = false; @@ -3819,10 +3685,10 @@ public boolean canProcessImmediately() { return false; } - // for implicit naming, we can do it immediately if the associated entity - // is bound and the reference is to its PK. For property-refs, we'd have to - // be *sure* that the column(s) for the referenced property is fully bound - // and we just cannot know that in today's model + // For implicit naming, we can do it immediately if the associated entity + // is bound and the reference is to its PK. For property-refs, we'd have to + // be *sure* that the column(s) for the referenced property is fully bound, + // and we just cannot know that in today's model. return manyToOneSource.getReferencedEntityAttributeName() == null; } @@ -3842,8 +3708,8 @@ public void doSecondPass(Map persistentClasses) { } else { // Otherwise we have some dependency resolution to do in order to perform - // implicit naming. If we get here, we assume that there is only a single - // column making up the FK + // implicit naming. If we get here, we assume that there is only a single + // column making up the FK. final PersistentClass referencedEntityBinding = mappingDocument.getMetadataCollector().getEntityBinding( referencedEntityName ); diff --git a/hibernate-core/src/main/java/org/hibernate/boot/registry/classloading/internal/AggregatedClassLoader.java b/hibernate-core/src/main/java/org/hibernate/boot/registry/classloading/internal/AggregatedClassLoader.java index be620359724d..b08beb96f77f 100644 --- a/hibernate-core/src/main/java/org/hibernate/boot/registry/classloading/internal/AggregatedClassLoader.java +++ b/hibernate-core/src/main/java/org/hibernate/boot/registry/classloading/internal/AggregatedClassLoader.java @@ -10,7 +10,6 @@ import java.util.Iterator; import java.util.LinkedHashSet; -import org.hibernate.internal.util.ExceptionHelper; public class AggregatedClassLoader extends ClassLoader { private final ClassLoader[] individualClassLoaders; @@ -122,7 +121,7 @@ else if ( !sysCLReturned && systemClassLoader != null ) { private Iterator newTcclNeverIterator() { final ClassLoader systemClassLoader = locateSystemClassLoader(); - return new Iterator() { + return new Iterator<>() { private int currentIndex = 0; private boolean sysCLReturned = false; @@ -182,7 +181,7 @@ public URL nextElement() { @Override protected URL findResource(String name) { - final Iterator clIterator = newClassLoaderIterator(); + final var clIterator = newClassLoaderIterator(); while ( clIterator.hasNext() ) { final ClassLoader classLoader = clIterator.next(); final URL resource = classLoader.getResource( name ); @@ -195,22 +194,18 @@ protected URL findResource(String name) { @Override protected Class findClass(String name) throws ClassNotFoundException { - final Iterator clIterator = newClassLoaderIterator(); - Throwable t = null; + final var clIterator = newClassLoaderIterator(); + final var exception = new ClassNotFoundException( "Could not load requested class: " + name ); while ( clIterator.hasNext() ) { final ClassLoader classLoader = clIterator.next(); try { return classLoader.loadClass( name ); } - catch (Exception ex) { - ExceptionHelper.combine( ( t == null ? t = new Throwable() : t ), ex ); - } - catch (LinkageError le) { - ExceptionHelper.combine( ( t == null ? t = new Throwable() : t ), le ); + catch (Exception|LinkageError ex) { + exception.addSuppressed( ex ); } } - - throw new ClassNotFoundException( "Could not load requested class : " + name, ( t != null && t.getSuppressed().length > 0 ? t : null ) ); + throw exception; } private static ClassLoader locateSystemClassLoader() { diff --git a/hibernate-core/src/main/java/org/hibernate/collection/spi/AbstractPersistentCollection.java b/hibernate-core/src/main/java/org/hibernate/collection/spi/AbstractPersistentCollection.java index 5342e5c7f978..42e9fef2e2ad 100644 --- a/hibernate-core/src/main/java/org/hibernate/collection/spi/AbstractPersistentCollection.java +++ b/hibernate-core/src/main/java/org/hibernate/collection/spi/AbstractPersistentCollection.java @@ -195,8 +195,8 @@ public int getSize() { final CollectionEntry entry = session.getPersistenceContextInternal().getCollectionEntry( this ); if ( entry == null ) { throwLazyInitializationExceptionIfNotConnected(); - throwLazyInitializationException("collection not associated with session"); - throw new AssertionFailure("impossible"); + throwLazyInitializationException( "collection not associated with session" ); + throw new AssertionFailure( "impossible" ); } else { if ( hasQueuedOperations() ) { @@ -233,7 +233,7 @@ private T withTemporarySessionIfNeeded(LazyInitializationWork lazyInitial tempSession = openTemporarySessionForLoading(); } else { - throwLazyInitializationException( "could not initialize proxy - no Session" ); + throwLazyInitializationException( "no session" ); } } else if ( !session.isOpenOrWaitingForAutoClose() ) { @@ -241,7 +241,7 @@ else if ( !session.isOpenOrWaitingForAutoClose() ) { tempSession = openTemporarySessionForLoading(); } else { - throwLazyInitializationException( "could not initialize proxy - the owning Session was closed" ); + throwLazyInitializationException( "the owning session was closed" ); } } else if ( !session.isConnected() ) { @@ -249,7 +249,7 @@ else if ( !session.isConnected() ) { tempSession = openTemporarySessionForLoading(); } else { - throwLazyInitializationException( "could not initialize proxy - the owning Session is disconnected" ); + throwLazyInitializationException( "the owning session is disconnected" ); } } @@ -273,8 +273,7 @@ else if ( !session.isConnected() ) { } final CollectionPersister collectionDescriptor = - session.getSessionFactory() - .getMappingMetamodel() + session.getSessionFactory().getMappingMetamodel() .getCollectionDescriptor( getRole() ); session.getPersistenceContextInternal() .addUninitializedDetachedCollection( collectionDescriptor, this ); @@ -301,20 +300,22 @@ else if ( !session.isConnected() ) { else { // Whenever the collection lazy loading is triggered during the loading process, // closing the connection will cause an error when RowProcessingStateStandardImpl#next() will be called. - final PersistenceContext persistenceContext = session.getPersistenceContext(); - if ( !session.isTransactionInProgress() - && ( !persistenceContext.hasLoadContext() - || persistenceContext.hasLoadContext() - && persistenceContext.getLoadContexts().isLoadingFinished() ) ) { + if ( !session.isTransactionInProgress() && !unfinishedLoading() ) { session.getJdbcCoordinator().afterTransaction(); } } } } + private boolean unfinishedLoading() { + final PersistenceContext persistenceContext = session.getPersistenceContext(); + return persistenceContext.hasLoadContext() + && !persistenceContext.getLoadContexts().isLoadingFinished(); + } + private SharedSessionContractImplementor openTemporarySessionForLoading() { if ( sessionFactoryUuid == null ) { - throwLazyInitializationException( "SessionFactory UUID not known to create temporary Session for loading" ); + throwLazyInitializationException( "SessionFactory UUID not known; cannot create temporary session for loading" ); } final SessionImplementor session = @@ -373,8 +374,8 @@ public boolean elementExists(Object element) { final CollectionEntry entry = session.getPersistenceContextInternal().getCollectionEntry( this ); if ( entry == null ) { throwLazyInitializationExceptionIfNotConnected(); - throwLazyInitializationException("collection not associated with session"); - throw new AssertionFailure("impossible"); + throwLazyInitializationException( "collection not associated with session" ); + throw new AssertionFailure( "impossible" ); } else { if ( hasQueuedOperations() ) { @@ -427,8 +428,8 @@ public Object elementByIndex(Object index) { final CollectionEntry entry = session.getPersistenceContextInternal().getCollectionEntry( this ); if ( entry == null ) { throwLazyInitializationExceptionIfNotConnected(); - throwLazyInitializationException("collection not associated with session"); - throw new AssertionFailure("impossible"); + throwLazyInitializationException( "collection not associated with session" ); + throw new AssertionFailure( "impossible" ); } else { if ( hasQueuedOperations() ) { @@ -646,9 +647,8 @@ private void throwLazyInitializationExceptionIfNotConnected() { private void throwLazyInitializationException(String message) { throw new LazyInitializationException( - "failed to lazily initialize a collection" + - (role == null ? "" : " of role: " + role) + - ": " + message + String.format( "Cannot lazily initialize collection%s (%s)", + role == null ? "" : " of role '" + role + "'", message ) ); } @@ -1305,11 +1305,7 @@ protected static Collection getOrphans( currentSaving.add( current ); } else { - final Object currentId = getEntityIdentifierIfNotUnsaved( - entityName, - current, - session - ); + final Object currentId = getEntityIdentifierIfNotUnsaved( entityName, current, session ); currentIds.add( useIdDirect ? currentId : new TypedValue( idType, currentId ) ); } } 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 2ceca2a07b83..c43e385585bb 100644 --- a/hibernate-core/src/main/java/org/hibernate/internal/SessionImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/internal/SessionImpl.java @@ -721,7 +721,7 @@ private void firePersist(final PersistEvent event) { } } if ( originalException != null ) { - ExceptionHelper.doThrow( originalException ); + ExceptionHelper.rethrow( originalException ); } } diff --git a/hibernate-core/src/main/java/org/hibernate/internal/util/ExceptionHelper.java b/hibernate-core/src/main/java/org/hibernate/internal/util/ExceptionHelper.java index 793c78dce10d..9ed77199f314 100644 --- a/hibernate-core/src/main/java/org/hibernate/internal/util/ExceptionHelper.java +++ b/hibernate-core/src/main/java/org/hibernate/internal/util/ExceptionHelper.java @@ -11,37 +11,28 @@ private ExceptionHelper() { } /** - * Throws the given throwable even if it is a checked exception. + * Throws the given {@link Throwable}, even if it's a checked exception. * - * @param e The throwable to throw. + * @param throwable The {@code Throwable} to throw. */ - public static void doThrow(Throwable e) { - ExceptionHelper.doThrow0(e); + public static void rethrow(Throwable throwable) { + sneakyThrow( throwable ); } - public static Throwable getRootCause(Throwable error) { - Throwable toProcess = error; - while ( toProcess.getCause() != null ) { - toProcess = toProcess.getCause(); - } - return toProcess; + @SuppressWarnings("unchecked") + private static void sneakyThrow(Throwable e) + throws T { + throw (T) e; } - public static T combine(T throwable, T otherThrowable) { - T toThrow = throwable; - if ( otherThrowable != null ) { - if ( toThrow != null ) { - toThrow.addSuppressed( otherThrowable ); - } - else { - toThrow = otherThrowable; + public static Throwable getRootCause(Throwable error) { + var next = error; + while ( true ) { + final var current = next; + next = current.getCause(); + if ( next == null ) { + return current; } } - return toThrow; - } - - @SuppressWarnings("unchecked") - private static void doThrow0(Throwable e) throws T { - throw (T) e; } } diff --git a/hibernate-core/src/main/java/org/hibernate/resource/transaction/backend/jdbc/internal/DdlTransactionIsolatorNonJtaImpl.java b/hibernate-core/src/main/java/org/hibernate/resource/transaction/backend/jdbc/internal/DdlTransactionIsolatorNonJtaImpl.java index 58e51eedb88e..a3920594c2a9 100644 --- a/hibernate-core/src/main/java/org/hibernate/resource/transaction/backend/jdbc/internal/DdlTransactionIsolatorNonJtaImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/resource/transaction/backend/jdbc/internal/DdlTransactionIsolatorNonJtaImpl.java @@ -122,7 +122,7 @@ public void release() { } } if ( originalException != null ) { - ExceptionHelper.doThrow( originalException ); + ExceptionHelper.rethrow( originalException ); } } } diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/actionqueue/CustomBeforeCompletionTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/actionqueue/CustomBeforeCompletionTest.java index e618b0579edd..cd1e2187dc13 100644 --- a/hibernate-core/src/test/java/org/hibernate/orm/test/actionqueue/CustomBeforeCompletionTest.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/actionqueue/CustomBeforeCompletionTest.java @@ -30,12 +30,7 @@ public class CustomBeforeCompletionTest extends BaseCoreFunctionalTestCase { public void success() { inSession( session -> { AtomicBoolean called = new AtomicBoolean( false ); - session.getActionQueue().registerProcess( new BeforeTransactionCompletionProcess() { - @Override - public void doBeforeTransactionCompletion(SessionImplementor session) { - called.set( true ); - } - } ); + session.getActionQueue().registerProcess( s -> called.set( true ) ); Assert.assertFalse( called.get() ); inTransaction( session, theSession -> { theSession.persist( new SimpleEntity( "jack" ) );