diff --git a/hibernate-core/src/main/java/org/hibernate/engine/internal/JoinHelper.java b/hibernate-core/src/main/java/org/hibernate/engine/internal/JoinHelper.java deleted file mode 100644 index 4ba002417c..0000000000 --- a/hibernate-core/src/main/java/org/hibernate/engine/internal/JoinHelper.java +++ /dev/null @@ -1,147 +0,0 @@ -/* - * Hibernate, Relational Persistence for Idiomatic Java - * - * License: GNU Lesser General Public License (LGPL), version 2.1 or later. - * See the lgpl.txt file in the root directory or . - */ -package org.hibernate.engine.internal; - -import org.hibernate.engine.spi.Mapping; -import org.hibernate.engine.spi.SessionFactoryImplementor; -import org.hibernate.internal.util.collections.ArrayHelper; -import org.hibernate.persister.entity.Joinable; -import org.hibernate.persister.entity.OuterJoinLoadable; -import org.hibernate.type.AssociationType; - -/** - * Helper for dealing with joins. - * - * @author Gavin King - */ -public final class JoinHelper { - - /** - * Get the unqualified names of the columns of the owning entity which are to be used in the join. - * - * @param type The association type for the association that represents the join - * @param property The name of the property that represents the association/join - * @param lhsPersister The persister for the left-hand side of the association/join - * @param mapping The mapping (typically the SessionFactory). - * - * @return The unqualified column names. - */ - public static String[] getLHSColumnNames( - AssociationType type, - int property, - OuterJoinLoadable lhsPersister, - Mapping mapping) { - return getLHSColumnNames( type, property, 0, lhsPersister, mapping ); - } - - /** - * Get the columns of the owning entity which are to be used in the join - * - * @param type The type representing the join - * @param property The property index for the association type - * @param begin ? - * @param lhsPersister The persister for the left-hand-side of the join - * @param mapping The mapping object (typically the SessionFactory) - * - * @return The columns for the left-hand-side of the join - */ - public static String[] getLHSColumnNames( - AssociationType type, - int property, - int begin, - OuterJoinLoadable lhsPersister, - Mapping mapping) { - if ( type.useLHSPrimaryKey() ) { - //return lhsPersister.getSubclassPropertyColumnNames(property); - return lhsPersister.getIdentifierColumnNames(); - } - else { - final String propertyName = type.getLHSPropertyName(); - if ( propertyName == null ) { - //slice, to get the columns for this component - //property - return ArrayHelper.slice( - property < 0 - ? lhsPersister.getIdentifierColumnNames() - : lhsPersister.getSubclassPropertyColumnNames( property ), - begin, - type.getColumnSpan( mapping ) - ); - } - else { - //property-refs for associations defined on a - //component are not supported, so no need to slice - return lhsPersister.getPropertyColumnNames( propertyName ); - } - } - } - - /** - * Determine the name of the table that is the left-hand-side of the join. Usually this is the - * name of the main table from the left-hand-side persister. But that is not the case with property-refs. - * - * @param type The type representing the join - * @param propertyIndex The property index for the type - * @param lhsPersister The persister for the left-hand-side of the join - * - * @return The table name - */ - public static String getLHSTableName( - AssociationType type, - int propertyIndex, - OuterJoinLoadable lhsPersister) { - if ( type.useLHSPrimaryKey() || propertyIndex < 0 ) { - return lhsPersister.getTableName(); - } - else { - final String propertyName = type.getLHSPropertyName(); - if ( propertyName == null ) { - //if there is no property-ref, assume the join - //is to the subclass table (ie. the table of the - //subclass that the association belongs to) - return lhsPersister.getSubclassPropertyTableName( propertyIndex ); - } - else { - //handle a property-ref - String propertyRefTable = lhsPersister.getPropertyTableName( propertyName ); - if ( propertyRefTable == null ) { - //it is possible that the tree-walking in OuterJoinLoader can get to - //an association defined by a subclass, in which case the property-ref - //might refer to a property defined on a subclass of the current class - //in this case, the table name is not known - this temporary solution - //assumes that the property-ref refers to a property of the subclass - //table that the association belongs to (a reasonable guess) - //TODO: fix this, add: OuterJoinLoadable.getSubclassPropertyTableName(String propertyName) - propertyRefTable = lhsPersister.getSubclassPropertyTableName( propertyIndex ); - } - return propertyRefTable; - } - } - } - - /** - * Get the columns of the associated table which are to be used in the join - * - * @param type The type - * @param factory The SessionFactory - * - * @return The columns for the right-hand-side of the join - */ - public static String[] getRHSColumnNames(AssociationType type, SessionFactoryImplementor factory) { - final String uniqueKeyPropertyName = type.getRHSUniqueKeyPropertyName(); - final Joinable joinable = type.getAssociatedJoinable( factory ); - if ( uniqueKeyPropertyName == null ) { - return joinable.getKeyColumnNames(); - } - else { - return ( (OuterJoinLoadable) joinable ).getPropertyColumnNames( uniqueKeyPropertyName ); - } - } - - private JoinHelper() { - } -} diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/EntityMappingType.java b/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/EntityMappingType.java index 74b9188a6a..3183e82895 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/EntityMappingType.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/EntityMappingType.java @@ -170,6 +170,10 @@ default boolean hasSubclasses() { return getEntityPersister().getEntityMetamodel().hasSubclasses(); } + default Set getSubclassEntityNames() { + return getEntityPersister().getEntityMetamodel().getSubclassEntityNames(); + } + AttributeMapping findDeclaredAttributeMapping(String name); /** diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/EntityCollectionPart.java b/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/EntityCollectionPart.java index c1a4675b3f..b10f0011f4 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/EntityCollectionPart.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/EntityCollectionPart.java @@ -21,6 +21,7 @@ import org.hibernate.mapping.IndexedCollection; import org.hibernate.mapping.Map; import org.hibernate.mapping.OneToMany; +import org.hibernate.mapping.PersistentClass; import org.hibernate.mapping.SimpleValue; import org.hibernate.mapping.ToOne; import org.hibernate.mapping.Value; @@ -66,8 +67,6 @@ import org.hibernate.sql.results.graph.entity.EntityFetch; import org.hibernate.sql.results.graph.entity.EntityValuedFetchable; import org.hibernate.sql.results.graph.entity.internal.EntityFetchJoinedImpl; -import org.hibernate.tuple.IdentifierProperty; -import org.hibernate.tuple.entity.EntityMetamodel; import org.hibernate.type.CompositeType; import org.hibernate.type.EntityType; import org.hibernate.type.Type; @@ -98,24 +97,26 @@ public EntityCollectionPart( this.nature = nature; this.entityMappingType = entityMappingType; final String referencedPropertyName; + final PersistentClass entityBinding; if ( bootModelValue instanceof OneToMany ) { final String mappedByProperty = collectionDescriptor.getMappedByProperty(); referencedPropertyName = mappedByProperty == null || mappedByProperty.isEmpty() ? null : mappedByProperty; + entityBinding = ( (OneToMany) bootModelValue ).getBuildingContext().getMetadataCollector() + .getEntityBinding( entityMappingType.getEntityName() ); } else { - referencedPropertyName = ( (ToOne) bootModelValue ).getReferencedPropertyName(); + final ToOne toOne = (ToOne) bootModelValue; + referencedPropertyName = toOne.getReferencedPropertyName(); + entityBinding = toOne.getBuildingContext().getMetadataCollector() + .getEntityBinding( entityMappingType.getEntityName() ); } if ( referencedPropertyName == null ) { final Set targetKeyPropertyNames = new HashSet<>( 2 ); targetKeyPropertyNames.add( EntityIdentifierMapping.ROLE_LOCAL_NAME ); - final IdentifierProperty identifierProperty = getEntityMappingType() - .getEntityPersister() - .getEntityMetamodel() - .getIdentifierProperty(); - final Type propertyType = identifierProperty.getType(); - if ( identifierProperty.getName() == null ) { + final Type propertyType = entityBinding.getIdentifier().getType(); + if ( entityBinding.getIdentifierProperty() == null ) { final CompositeType compositeType; if ( propertyType.isComponentType() && ( compositeType = (CompositeType) propertyType ).isEmbedded() && compositeType.getPropertyNames().length == 1 ) { @@ -138,7 +139,7 @@ public EntityCollectionPart( else { ToOneAttributeMapping.addPrefixedPropertyNames( targetKeyPropertyNames, - identifierProperty.getName(), + entityBinding.getIdentifierProperty().getName(), propertyType, creationProcess.getCreationContext().getSessionFactory() ); @@ -162,9 +163,7 @@ else if ( bootModelValue instanceof OneToMany ) { this.targetKeyPropertyNames = targetKeyPropertyNames; } else { - final EntityMetamodel entityMetamodel = entityMappingType.getEntityPersister().getEntityMetamodel(); - final int propertyIndex = entityMetamodel.getPropertyIndex( referencedPropertyName ); - final Type propertyType = entityMetamodel.getPropertyTypes()[propertyIndex]; + final Type propertyType = entityBinding.getProperty( referencedPropertyName ).getType(); final CompositeType compositeType; if ( propertyType.isComponentType() && ( compositeType = (CompositeType) propertyType ).isEmbedded() && compositeType.getPropertyNames().length == 1 ) { diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/ToOneAttributeMapping.java b/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/ToOneAttributeMapping.java index 787375b352..a71786b690 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/ToOneAttributeMapping.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/ToOneAttributeMapping.java @@ -91,8 +91,6 @@ import org.hibernate.sql.results.graph.entity.internal.EntityResultJoinedSubclassImpl; import org.hibernate.sql.results.internal.domain.CircularBiDirectionalFetchImpl; import org.hibernate.sql.results.internal.domain.CircularFetchImpl; -import org.hibernate.tuple.IdentifierProperty; -import org.hibernate.tuple.entity.EntityMetamodel; import org.hibernate.type.ComponentType; import org.hibernate.type.CompositeType; import org.hibernate.type.EmbeddedComponentType; @@ -363,12 +361,10 @@ the navigable path is NavigablePath(Card.fields.{element}.{id}.card) and it does if ( referencedPropertyName == null ) { final Set targetKeyPropertyNames = new HashSet<>( 2 ); targetKeyPropertyNames.add( EntityIdentifierMapping.ROLE_LOCAL_NAME ); - final IdentifierProperty identifierProperty = getEntityMappingType() - .getEntityPersister() - .getEntityMetamodel() - .getIdentifierProperty(); - final Type propertyType = identifierProperty.getType(); - if ( identifierProperty.getName() == null ) { + final PersistentClass entityBinding = bootValue.getBuildingContext().getMetadataCollector() + .getEntityBinding( entityMappingType.getEntityName() ); + final Type propertyType = entityBinding.getIdentifier().getType(); + if ( entityBinding.getIdentifierProperty() == null ) { final CompositeType compositeType; if ( propertyType.isComponentType() && ( compositeType = (CompositeType) propertyType ).isEmbedded() && compositeType.getPropertyNames().length == 1 ) { @@ -397,7 +393,7 @@ the navigable path is NavigablePath(Card.fields.{element}.{id}.card) and it does } } else { - this.targetKeyPropertyName = identifierProperty.getName(); + this.targetKeyPropertyName = entityBinding.getIdentifierProperty().getName(); addPrefixedPropertyNames( targetKeyPropertyNames, targetKeyPropertyName, @@ -419,9 +415,9 @@ else if ( bootValue.isReferenceToPrimaryKey() ) { this.targetKeyPropertyNames = targetKeyPropertyNames; } else { - final EntityMetamodel entityMetamodel = entityMappingType.getEntityPersister().getEntityMetamodel(); - final int propertyIndex = entityMetamodel.getPropertyIndex( referencedPropertyName ); - final Type propertyType = entityMetamodel.getPropertyTypes()[propertyIndex]; + final PersistentClass entityBinding = bootValue.getBuildingContext().getMetadataCollector() + .getEntityBinding( entityMappingType.getEntityName() ); + final Type propertyType = entityBinding.getProperty( referencedPropertyName ).getType(); final CompositeType compositeType; if ( propertyType.isComponentType() && ( compositeType = (CompositeType) propertyType ).isEmbedded() && compositeType.getPropertyNames().length == 1 ) { @@ -1165,8 +1161,11 @@ private boolean isSelectByUniqueKey(ForeignKeyDescriptor.Nature side) { else { // case 1.1 // Make sure the entity identifier is not a target key property i.e. this really is a unique key mapping - return bidirectionalAttributeName != null && !targetKeyPropertyNames.contains( - entityMappingType.getEntityPersister().getEntityMetamodel().getIdentifierProperty().getName() + return bidirectionalAttributeName != null && ( + !( entityMappingType.getIdentifierMapping() instanceof SingleAttributeIdentifierMapping ) + || !targetKeyPropertyNames.contains( + ( (SingleAttributeIdentifierMapping) entityMappingType.getIdentifierMapping() ).getAttributeName() + ) ); } } diff --git a/hibernate-core/src/main/java/org/hibernate/persister/entity/AbstractEntityPersister.java b/hibernate-core/src/main/java/org/hibernate/persister/entity/AbstractEntityPersister.java index ba6b91b3e2..e26542192a 100644 --- a/hibernate-core/src/main/java/org/hibernate/persister/entity/AbstractEntityPersister.java +++ b/hibernate-core/src/main/java/org/hibernate/persister/entity/AbstractEntityPersister.java @@ -26,9 +26,7 @@ import java.util.Objects; import java.util.Set; import java.util.SortedMap; -import java.util.SortedSet; import java.util.TreeMap; -import java.util.TreeSet; import java.util.function.BiConsumer; import java.util.function.Consumer; import java.util.function.Supplier; @@ -156,6 +154,7 @@ import org.hibernate.metamodel.mapping.AttributeMetadata; import org.hibernate.metamodel.mapping.AttributeMetadataAccess; import org.hibernate.metamodel.mapping.BasicValuedModelPart; +import org.hibernate.metamodel.mapping.DiscriminatedAssociationModelPart; import org.hibernate.metamodel.mapping.EmbeddableValuedModelPart; import org.hibernate.metamodel.mapping.EntityDiscriminatorMapping; import org.hibernate.metamodel.mapping.EntityIdentifierMapping; @@ -172,6 +171,7 @@ import org.hibernate.metamodel.mapping.PluralAttributeMapping; import org.hibernate.metamodel.mapping.Queryable; import org.hibernate.metamodel.mapping.SelectableConsumer; +import org.hibernate.metamodel.mapping.SelectableMapping; import org.hibernate.metamodel.mapping.SingularAttributeMapping; import org.hibernate.metamodel.mapping.StateArrayContributorMapping; import org.hibernate.metamodel.mapping.StateArrayContributorMetadata; @@ -188,6 +188,7 @@ import org.hibernate.metamodel.mapping.internal.MappingModelCreationHelper; import org.hibernate.metamodel.mapping.internal.MappingModelCreationProcess; import org.hibernate.metamodel.mapping.internal.SimpleNaturalIdMapping; +import org.hibernate.metamodel.mapping.internal.ToOneAttributeMapping; import org.hibernate.metamodel.model.domain.NavigableRole; import org.hibernate.metamodel.spi.EntityInstantiator; import org.hibernate.metamodel.spi.EntityRepresentationStrategy; @@ -2313,6 +2314,32 @@ else if ( isClassOrSuperclassTable( tableIndex ) ) { } } + @Override + public String getPropertyTableName(String propertyName) { + final AttributeMapping attributeMapping = findAttributeMapping( propertyName ); + if ( attributeMapping instanceof SelectableMapping ) { + return ( (SelectableMapping) attributeMapping ).getContainingTableExpression(); + } + else if ( attributeMapping instanceof EmbeddableValuedModelPart ) { + return ( (EmbeddableValuedModelPart) attributeMapping ).getContainingTableExpression(); + } + else if ( attributeMapping instanceof DiscriminatedAssociationModelPart ) { + return ( (DiscriminatedAssociationModelPart) attributeMapping ).getDiscriminatorPart() + .getContainingTableExpression(); + } + else if ( attributeMapping instanceof ToOneAttributeMapping ) { + final ToOneAttributeMapping toOneAttributeMapping = (ToOneAttributeMapping) attributeMapping; + if ( toOneAttributeMapping.getSideNature() == ForeignKeyDescriptor.Nature.KEY ) { + return toOneAttributeMapping.getForeignKeyDescriptor().getKeyTable(); + } + else { + return toOneAttributeMapping.getForeignKeyDescriptor().getTargetTable(); + } + } + assert attributeMapping instanceof PluralAttributeMapping; + return ( (PluralAttributeMapping) attributeMapping ).getKeyDescriptor().getKeyTable(); + } + private DiscriminatorMetadata discriminatorMetadata; @Override @@ -2441,27 +2468,38 @@ public int[] resolveAttributeIndexes(String[] attributeNames) { if ( attributeNames == null || attributeNames.length == 0 ) { return ArrayHelper.EMPTY_INT_ARRAY; } - int[] fields = new int[attributeNames.length]; - int counter = 0; + final List fields = new ArrayList<>( attributeNames.length ); - // We sort to get rid of duplicates + // Sort attribute names so that we can traverse mappings efficiently Arrays.sort( attributeNames ); - Integer index0 = entityMetamodel.getPropertyIndexOrNull( attributeNames[0] ); - if ( index0 != null ) { - fields[counter++] = index0; - } - - for ( int i = 0, j = 1; j < attributeNames.length; ++i, ++j ) { - if ( !attributeNames[i].equals( attributeNames[j] ) ) { - Integer index = entityMetamodel.getPropertyIndexOrNull( attributeNames[j] ); - if ( index != null ) { - fields[counter++] = index; + int index = 0; + for ( final AttributeMapping attributeMapping : attributeMappings ) { + final String attributeName = attributeMapping.getAttributeName(); + final int nameLength = attributeName.length(); + final String currentAttributeName = attributeNames[index]; + if ( currentAttributeName.startsWith( attributeName ) && ( + ( currentAttributeName.length() == nameLength || currentAttributeName.charAt( nameLength ) == '.' ) ) ) { + fields.add( ( (StateArrayContributorMapping) attributeMapping ).getStateArrayPosition() ); + index++; + if ( index < attributeNames.length ) { + // Skip duplicates + do { + if ( attributeNames[index].equals( attributeMapping.getAttributeName() ) ) { + index++; + } + else { + break; + } + } while ( index < attributeNames.length ); + } + else { + break; } } } - return Arrays.copyOf( fields, counter ); + return ArrayHelper.toIntArray( fields ); } @Override @@ -2498,11 +2536,38 @@ public int[] resolveDirtyAttributeIndexes( } ); } - final boolean[] propertyUpdateability = entityMetamodel.getPropertyUpdateability(); - for ( String attributeName : attributeNames ) { - final Integer index = entityMetamodel.getPropertyIndexOrNull( attributeName ); - if ( index != null && propertyUpdateability[index] && !fields.contains( index ) ) { - fields.add( index ); + if ( attributeNames.length != 0 ) { + final boolean[] propertyUpdateability = entityMetamodel.getPropertyUpdateability(); + + // Sort attribute names so that we can traverse mappings efficiently + Arrays.sort( attributeNames ); + int index = 0; + for ( final AttributeMapping attributeMapping : attributeMappings ) { + final String attributeName = attributeMapping.getAttributeName(); + final int nameLength = attributeName.length(); + final String currentAttributeName = attributeNames[index]; + int position = ( (StateArrayContributorMapping) attributeMapping ).getStateArrayPosition(); + if ( currentAttributeName.startsWith( attributeName ) && ( + ( currentAttributeName.length() == nameLength || currentAttributeName.charAt( nameLength ) == '.' ) ) ) { + if ( propertyUpdateability[position] && !fields.contains( position ) ) { + fields.add( position ); + } + index++; + if ( index < attributeNames.length ) { + // Skip duplicates + do { + if ( attributeNames[index].equals( attributeName ) ) { + index++; + } + else { + break; + } + } while ( index < attributeNames.length ); + } + else { + break; + } + } } } @@ -2681,14 +2746,6 @@ public int getPropertyIndex(String propertyName) { return entityMetamodel.getPropertyIndex( propertyName ); } - protected String getSQLWhereString(String alias) { - return StringHelper.replace( sqlWhereStringTemplate, Template.TEMPLATE, alias ); - } - - protected boolean hasWhere() { - return sqlWhereStringTemplate != null; - } - private void initOrdinaryPropertyPaths(Metadata mapping) throws MappingException { for ( int i = 0; i < getSubclassPropertyNameClosure().length; i++ ) { propertyMapping.initPropertyPaths( @@ -4003,12 +4060,6 @@ public void applyWhereRestrictions(Consumer predicateConsumer, TableG predicateConsumer.accept( new SqlFragmentPredicate( fragment ) ); } - protected String filterFragment(String alias) throws MappingException { - return filterFragment( alias, Collections.emptySet() ); - } - - protected abstract String filterFragment(String alias, Set treatAsDeclarations); - @Override public String generateFilterConditionAlias(String rootAlias) { return rootAlias; @@ -6031,7 +6082,7 @@ private AttributeMapping generateNonIdAttributeMapping( final int propertyIndex = getPropertyIndex( bootProperty.getName() ); - final String tableExpression = getPropertyTableName( attrName ); + final String tableExpression = getTableName( getPropertyTableNumbers()[propertyIndex] ); final String[] attrColumnNames = getPropertyColumnNames( propertyIndex ); final PropertyAccess propertyAccess = getRepresentationStrategy().resolvePropertyAccess( bootProperty ); diff --git a/hibernate-core/src/main/java/org/hibernate/persister/entity/JoinedSubclassEntityPersister.java b/hibernate-core/src/main/java/org/hibernate/persister/entity/JoinedSubclassEntityPersister.java index 6c3d426e08..17b8166631 100644 --- a/hibernate-core/src/main/java/org/hibernate/persister/entity/JoinedSubclassEntityPersister.java +++ b/hibernate-core/src/main/java/org/hibernate/persister/entity/JoinedSubclassEntityPersister.java @@ -40,14 +40,26 @@ import org.hibernate.mapping.Subclass; import org.hibernate.mapping.Table; import org.hibernate.mapping.Value; +import org.hibernate.metamodel.mapping.AttributeMapping; +import org.hibernate.metamodel.mapping.DiscriminatedAssociationModelPart; +import org.hibernate.metamodel.mapping.EmbeddableValuedModelPart; import org.hibernate.metamodel.mapping.EntityDiscriminatorMapping; import org.hibernate.metamodel.mapping.EntityIdentifierMapping; import org.hibernate.metamodel.mapping.EntityMappingType; import org.hibernate.metamodel.mapping.EntityVersionMapping; +import org.hibernate.metamodel.mapping.ForeignKeyDescriptor; +import org.hibernate.metamodel.mapping.ModelPart; +import org.hibernate.metamodel.mapping.PluralAttributeMapping; +import org.hibernate.metamodel.mapping.SelectableMapping; +import org.hibernate.metamodel.mapping.SingularAttributeMapping; +import org.hibernate.metamodel.mapping.StateArrayContributorMapping; +import org.hibernate.metamodel.mapping.internal.BasicAttributeMapping; import org.hibernate.metamodel.mapping.internal.BasicEntityIdentifierMappingImpl; import org.hibernate.metamodel.mapping.internal.CaseStatementDiscriminatorMappingImpl; +import org.hibernate.metamodel.mapping.internal.EmbeddedAttributeMapping; import org.hibernate.metamodel.mapping.internal.MappingModelCreationHelper; import org.hibernate.metamodel.mapping.internal.MappingModelCreationProcess; +import org.hibernate.metamodel.mapping.internal.ToOneAttributeMapping; import org.hibernate.metamodel.spi.MappingMetamodelImplementor; import org.hibernate.metamodel.spi.RuntimeModelCreationContext; import org.hibernate.persister.spi.PersisterCreationContext; @@ -108,7 +120,7 @@ public class JoinedSubclassEntityPersister extends AbstractEntityPersister { // properties of this class, including inherited properties private final int[] naturalOrderPropertyTableNumbers; - private final int[] propertyTableNumbers; +// private final int[] propertyTableNumbers; // the closure of all properties in the entire hierarchy including // subclasses and superclasses of this class @@ -446,13 +458,13 @@ public JoinedSubclassEntityPersister( // PROPERTIES int hydrateSpan = getPropertySpan(); naturalOrderPropertyTableNumbers = new int[hydrateSpan]; - propertyTableNumbers = new int[hydrateSpan]; +// propertyTableNumbers = new int[hydrateSpan]; List propertyClosure = persistentClass.getPropertyClosure(); for ( int i = 0; i < propertyClosure.size(); i++ ) { String tableName = propertyClosure.get(i).getValue().getTable().getQualifiedName( factory.getSqlStringGenerationContext() ); - propertyTableNumbers[i] = getTableId( tableName, this.tableNames ); +// propertyTableNumbers[i] = getTableId( tableName, this.tableNames ); naturalOrderPropertyTableNumbers[i] = getTableId( tableName, naturalOrderTableNames ); } @@ -879,16 +891,6 @@ public String getTableName() { return tableNames[0]; } - @Override - protected String filterFragment(String alias) { - return hasWhere() ? getSQLWhereString( generateFilterConditionAlias( alias ) ) : ""; - } - - @Override - protected String filterFragment(String alias, Set treatAsDeclarations) { - return filterFragment( alias ); - } - @Override public String generateFilterConditionAlias(String rootAlias) { return generateTableAlias( rootAlias, tableSpan - 1 ); @@ -999,15 +1001,6 @@ private String[] getSubclassNameClosureBySubclassTable(int subclassTableNumber) return subclassNamesBySubclassTable[index]; } - @Override - public String getPropertyTableName(String propertyName) { - Integer index = getEntityMetamodel().getPropertyIndexOrNull( propertyName ); - if ( index == null ) { - return null; - } - return tableNames[propertyTableNumbers[index]]; - } - @Override public String[] getConstraintOrderedTableNameClosure() { return constraintOrderedTableNames; diff --git a/hibernate-core/src/main/java/org/hibernate/persister/entity/SingleTableEntityPersister.java b/hibernate-core/src/main/java/org/hibernate/persister/entity/SingleTableEntityPersister.java index 26d3793ff6..06b38b7442 100644 --- a/hibernate-core/src/main/java/org/hibernate/persister/entity/SingleTableEntityPersister.java +++ b/hibernate-core/src/main/java/org/hibernate/persister/entity/SingleTableEntityPersister.java @@ -37,6 +37,7 @@ import org.hibernate.mapping.Subclass; import org.hibernate.mapping.Table; import org.hibernate.mapping.Value; +import org.hibernate.metamodel.spi.MappingMetamodelImplementor; import org.hibernate.metamodel.spi.RuntimeModelCreationContext; import org.hibernate.persister.spi.PersisterCreationContext; import org.hibernate.query.sqm.ComparisonOperator; @@ -562,90 +563,10 @@ public String fromTableFragment(String name) { return getTableName() + ' ' + name; } - @Override - protected String filterFragment(String alias) throws MappingException { - if ( hasWhere() ) { - return discriminatorFilterFragment( alias ) + " and " + getSQLWhereString( alias ); - } - else { - return ""; - } - } - - private String discriminatorFilterFragment(String alias) throws MappingException { - return discriminatorFilterFragment( alias, null ); - } - - @Override - protected String filterFragment(String alias, Set treatAsDeclarations) { - if ( hasWhere() ) { - final String discriminatorFilterFragment = discriminatorFilterFragment( alias, treatAsDeclarations ); - if ( StringHelper.isNotEmpty( discriminatorFilterFragment ) ) { - return discriminatorFilterFragment + " and " + getSQLWhereString( alias ); - } - return getSQLWhereString( alias ); - } - else { - return ""; - } - } - - private String discriminatorFilterFragment(String alias, Set treatAsDeclarations) { - final boolean hasTreatAs = treatAsDeclarations != null && !treatAsDeclarations.isEmpty(); - - if ( !needsDiscriminator() && !hasTreatAs ) { - return ""; - } - - final InFragment frag = new InFragment(); - if ( isDiscriminatorFormula() ) { - frag.setFormula( alias, getDiscriminatorFormulaTemplate() ); - } - else { - frag.setColumn( alias, getDiscriminatorColumnName() ); - } - - frag.addValues( hasTreatAs ? decodeTreatAsRequests( treatAsDeclarations ) : fullDiscriminatorSQLValues ); - - return frag.toFragmentString(); - } - private boolean needsDiscriminator() { return forceDiscriminator || isInherited(); } - private String[] decodeTreatAsRequests(Set treatAsDeclarations) { - final List values = new ArrayList<>(); - for ( String subclass : treatAsDeclarations ) { - final Queryable queryable = (Queryable) getFactory() - .getRuntimeMetamodels() - .getMappingMetamodel() - .getEntityDescriptor( subclass ); - if ( !queryable.isAbstract() ) { - values.add( queryable.getDiscriminatorSQLValue() ); - } - if ( queryable.hasSubclasses() ) { - // if the treat is an abstract class, add the concrete implementations to values if any - Set actualSubClasses = queryable.getEntityMetamodel().getSubclassEntityNames(); - - for ( String actualSubClass : actualSubClasses ) { - if ( actualSubClass.equals( subclass ) ) { - continue; - } - - final Queryable actualQueryable = (Queryable) getFactory() - .getRuntimeMetamodels() - .getMappingMetamodel() - .getEntityDescriptor( actualSubClass ); - if ( !actualQueryable.hasSubclasses() ) { - values.add( actualQueryable.getDiscriminatorSQLValue() ); - } - } - } - } - return ArrayHelper.toStringArray( values ); - } - @Override public String getSubclassPropertyTableName(int i) { return subclassTableNameClosure[subclassPropertyTableNumberClosure[i]]; @@ -715,12 +636,6 @@ protected boolean isNullableSubclassTable(int j) { return isNullableSubclassTable[j]; } - @Override - public String getPropertyTableName(String propertyName) { - Integer index = getEntityMetamodel().getPropertyIndexOrNull( propertyName ); - return index == null ? null : qualifiedTableNames[propertyTableNumbers[index]]; - } - @Override protected boolean hasMultipleTables() { return getTableSpan() > 1; @@ -880,10 +795,47 @@ else if ( discriminatorValue == DiscriminatorHelper.NOT_NULL_DISCRIMINATOR ) { @Override public void pruneForSubclasses(TableGroup tableGroup, Set treatedEntityNames) { + if ( !needsDiscriminator() && treatedEntityNames.isEmpty() ) { + return; + } // The optimization is to simply add the discriminator filter fragment for all treated entity names final NamedTableReference tableReference = (NamedTableReference) tableGroup.getPrimaryTableReference(); + + final InFragment frag = new InFragment(); + if ( isDiscriminatorFormula() ) { + frag.setFormula( "t", getDiscriminatorFormulaTemplate() ); + } + else { + frag.setColumn( "t", getDiscriminatorColumnName() ); + } + + final MappingMetamodelImplementor mappingMetamodel = getFactory() + .getRuntimeMetamodels() + .getMappingMetamodel(); + for ( String subclass : treatedEntityNames ) { + final Queryable queryable = (Queryable) mappingMetamodel.getEntityDescriptor( subclass ); + if ( !queryable.isAbstract() ) { + frag.addValue( queryable.getDiscriminatorSQLValue() ); + } + if ( queryable.hasSubclasses() ) { + // if the treat is an abstract class, add the concrete implementations to values if any + Set actualSubClasses = queryable.getSubclassEntityNames(); + + for ( String actualSubClass : actualSubClasses ) { + if ( actualSubClass.equals( subclass ) ) { + continue; + } + + final Queryable actualQueryable = (Queryable) mappingMetamodel.getEntityDescriptor( actualSubClass ); + if ( !actualQueryable.hasSubclasses() ) { + frag.addValue( actualQueryable.getDiscriminatorSQLValue() ); + } + } + } + } + tableReference.setPrunedTableExpression( - "(select * from " + getTableName() + " t where " + discriminatorFilterFragment( "t", treatedEntityNames ) + ")" + "(select * from " + getTableName() + " t where " + frag.toFragmentString() + ")" ); } diff --git a/hibernate-core/src/main/java/org/hibernate/persister/entity/UnionSubclassEntityPersister.java b/hibernate-core/src/main/java/org/hibernate/persister/entity/UnionSubclassEntityPersister.java index 237c1292e4..bbec74c85f 100644 --- a/hibernate-core/src/main/java/org/hibernate/persister/entity/UnionSubclassEntityPersister.java +++ b/hibernate-core/src/main/java/org/hibernate/persister/entity/UnionSubclassEntityPersister.java @@ -351,16 +351,6 @@ public String fromTableFragment(String name) { return getTableName() + ' ' + name; } - @Override - protected String filterFragment(String name) { - return hasWhere() ? getSQLWhereString( name ) : ""; - } - - @Override - protected String filterFragment(String alias, Set treatAsDeclarations) { - return filterFragment( alias ); - } - @Override public String getSubclassPropertyTableName(int i) { return getTableName();//ie. the subquery! yuck! @@ -524,7 +514,7 @@ protected String generateSubquery(Set treated) { final StringBuilder buf = new StringBuilder( subquery.length() ) .append( "( " ); - for ( String name : getEntityMetamodel().getSubclassEntityNames() ) { + for ( String name : getSubclassEntityNames() ) { final AbstractEntityPersister persister = (AbstractEntityPersister) metamodel.findEntityDescriptor( name ); final String subclassTableName = persister.getTableName(); if ( treatedTableNames.contains( subclassTableName ) ) { @@ -595,12 +585,6 @@ protected boolean isClassOrSuperclassTable(int j) { return true; } - @Override - public String getPropertyTableName(String propertyName) { - //TODO: check this.... - return getTableName(); - } - @Override public String[] getConstraintOrderedTableNameClosure() { return constraintOrderedTableNames; diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/sql/BaseSqmToSqlAstConverter.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/sql/BaseSqmToSqlAstConverter.java index 7452570f46..770e61870e 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/sql/BaseSqmToSqlAstConverter.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/sql/BaseSqmToSqlAstConverter.java @@ -3989,7 +3989,7 @@ private Expression withTreatRestriction(Expression expression, SqmPath path) treatedPath.getTreatTarget().getHibernateEntityName() ); conjunctTreatUsages.computeIfAbsent( treatedPath.getWrappedPath(), p -> new HashSet<>( 1 ) ) - .addAll( entityDescriptor.getEntityMetamodel().getSubclassEntityNames() ); + .addAll( entityDescriptor.getSubclassEntityNames() ); return expression; } // Note: If the columns that are accessed are not shared with other entities, we could avoid this wrapping @@ -4039,7 +4039,7 @@ private Predicate createTreatTypeRestriction(SqmPath lhs, EntityDomainType .getRuntimeMetamodels() .getMappingMetamodel(); final EntityPersister entityDescriptor = domainModel.findEntityDescriptor( treatTarget.getHibernateEntityName() ); - final Set subclassEntityNames = entityDescriptor.getEntityMetamodel().getSubclassEntityNames(); + final Set subclassEntityNames = entityDescriptor.getSubclassEntityNames(); return createTreatTypeRestriction( lhs, subclassEntityNames ); } diff --git a/hibernate-core/src/main/java/org/hibernate/sql/results/graph/collection/internal/AbstractCollectionInitializer.java b/hibernate-core/src/main/java/org/hibernate/sql/results/graph/collection/internal/AbstractCollectionInitializer.java index aa0e1da84e..ddc1dca5ad 100644 --- a/hibernate-core/src/main/java/org/hibernate/sql/results/graph/collection/internal/AbstractCollectionInitializer.java +++ b/hibernate-core/src/main/java/org/hibernate/sql/results/graph/collection/internal/AbstractCollectionInitializer.java @@ -91,7 +91,7 @@ protected boolean isAttributeAssignableToConcreteDescriptor() { if ( concreteDescriptor.isPolymorphic() ) { final AbstractEntityPersister declaringType = (AbstractEntityPersister) collectionAttributeMapping.getDeclaringType(); if ( concreteDescriptor != declaringType ) { - if ( !declaringType.getEntityMetamodel().getSubclassEntityNames().contains( concreteDescriptor.getEntityMetamodel().getName() ) ) { + if ( !declaringType.getSubclassEntityNames().contains( concreteDescriptor.getName() ) ) { return false; } } diff --git a/hibernate-core/src/main/java/org/hibernate/sql/results/graph/entity/internal/BatchEntitySelectFetchInitializer.java b/hibernate-core/src/main/java/org/hibernate/sql/results/graph/entity/internal/BatchEntitySelectFetchInitializer.java index f0964cb4a6..17c5d55dec 100644 --- a/hibernate-core/src/main/java/org/hibernate/sql/results/graph/entity/internal/BatchEntitySelectFetchInitializer.java +++ b/hibernate-core/src/main/java/org/hibernate/sql/results/graph/entity/internal/BatchEntitySelectFetchInitializer.java @@ -157,7 +157,7 @@ protected boolean isAttributeAssignableToConcreteDescriptor() { if ( concreteDescriptor.isPolymorphic() ) { final AbstractEntityPersister declaringType = (AbstractEntityPersister) referencedModelPart.getDeclaringType(); if ( concreteDescriptor != declaringType ) { - if ( !declaringType.getEntityMetamodel().getSubclassEntityNames().contains( concreteDescriptor.getEntityMetamodel().getName() ) ) { + if ( !declaringType.getSubclassEntityNames().contains( concreteDescriptor.getName() ) ) { return false; } } diff --git a/hibernate-core/src/main/java/org/hibernate/sql/results/graph/entity/internal/EntityDelayedFetchInitializer.java b/hibernate-core/src/main/java/org/hibernate/sql/results/graph/entity/internal/EntityDelayedFetchInitializer.java index dc9b6b3a89..8c1ee05d99 100644 --- a/hibernate-core/src/main/java/org/hibernate/sql/results/graph/entity/internal/EntityDelayedFetchInitializer.java +++ b/hibernate-core/src/main/java/org/hibernate/sql/results/graph/entity/internal/EntityDelayedFetchInitializer.java @@ -178,7 +178,7 @@ protected boolean isAttributeAssignableToConcreteDescriptor() { if ( concreteDescriptor.isPolymorphic() ) { final AbstractEntityPersister declaringType = (AbstractEntityPersister) referencedModelPart.getDeclaringType(); if ( concreteDescriptor != declaringType ) { - if ( !declaringType.getEntityMetamodel().getSubclassEntityNames().contains( concreteDescriptor.getEntityMetamodel().getName() ) ) { + if ( !declaringType.getSubclassEntityNames().contains( concreteDescriptor.getName() ) ) { return false; } } diff --git a/hibernate-core/src/main/java/org/hibernate/sql/results/graph/entity/internal/EntitySelectFetchInitializer.java b/hibernate-core/src/main/java/org/hibernate/sql/results/graph/entity/internal/EntitySelectFetchInitializer.java index 90ec871ef2..af25f46e0c 100644 --- a/hibernate-core/src/main/java/org/hibernate/sql/results/graph/entity/internal/EntitySelectFetchInitializer.java +++ b/hibernate-core/src/main/java/org/hibernate/sql/results/graph/entity/internal/EntitySelectFetchInitializer.java @@ -218,7 +218,7 @@ protected boolean isAttributeAssignableToConcreteDescriptor() { if ( concreteDescriptor.isPolymorphic() ) { final AbstractEntityPersister declaringType = (AbstractEntityPersister) referencedModelPart.getDeclaringType(); if ( concreteDescriptor != declaringType ) { - if ( !declaringType.getEntityMetamodel().getSubclassEntityNames().contains( concreteDescriptor.getEntityMetamodel().getName() ) ) { + if ( !declaringType.getSubclassEntityNames().contains( concreteDescriptor.getName() ) ) { return false; } } diff --git a/hibernate-core/src/main/java/org/hibernate/tuple/AbstractAttribute.java b/hibernate-core/src/main/java/org/hibernate/tuple/AbstractAttribute.java index 2354717d86..b38a73eacc 100644 --- a/hibernate-core/src/main/java/org/hibernate/tuple/AbstractAttribute.java +++ b/hibernate-core/src/main/java/org/hibernate/tuple/AbstractAttribute.java @@ -11,7 +11,7 @@ /** * @author Steve Ebersole */ -public abstract class AbstractAttribute implements Attribute, Property { +public abstract class AbstractAttribute implements Attribute { private final String attributeName; private final Type attributeType; @@ -20,11 +20,6 @@ protected AbstractAttribute(String attributeName, Type attributeType) { this.attributeType = attributeType; } - @Override - public String getNode() { - return null; - } - @Override public String getName() { return attributeName; diff --git a/hibernate-core/src/main/java/org/hibernate/tuple/IdentifierAttribute.java b/hibernate-core/src/main/java/org/hibernate/tuple/IdentifierAttribute.java index bbccc33d36..abbdef3c80 100644 --- a/hibernate-core/src/main/java/org/hibernate/tuple/IdentifierAttribute.java +++ b/hibernate-core/src/main/java/org/hibernate/tuple/IdentifierAttribute.java @@ -11,7 +11,7 @@ /** * @author Steve Ebersole */ -public interface IdentifierAttribute extends Attribute, Property { +public interface IdentifierAttribute extends Attribute { boolean isVirtual(); boolean isEmbedded(); diff --git a/hibernate-core/src/main/java/org/hibernate/tuple/Property.java b/hibernate-core/src/main/java/org/hibernate/tuple/Property.java deleted file mode 100644 index 65e8526680..0000000000 --- a/hibernate-core/src/main/java/org/hibernate/tuple/Property.java +++ /dev/null @@ -1,23 +0,0 @@ -/* - * Hibernate, Relational Persistence for Idiomatic Java - * - * License: GNU Lesser General Public License (LGPL), version 2.1 or later. - * See the lgpl.txt file in the root directory or . - */ -package org.hibernate.tuple; - -/** - * Defines the basic contract of a Property within the runtime metamodel. - * - * @author Steve Ebersole - * - * @deprecated Use the direct {@link Attribute} hierarchy - */ -@Deprecated -public interface Property extends Attribute { - /** - * @deprecated DOM4j entity mode is no longer supported - */ - @Deprecated - String getNode(); -} diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/strategy/internal/ValidityAuditStrategy.java b/hibernate-envers/src/main/java/org/hibernate/envers/strategy/internal/ValidityAuditStrategy.java index 3539885b2e..946b68da56 100644 --- a/hibernate-envers/src/main/java/org/hibernate/envers/strategy/internal/ValidityAuditStrategy.java +++ b/hibernate-envers/src/main/java/org/hibernate/envers/strategy/internal/ValidityAuditStrategy.java @@ -511,7 +511,7 @@ private List getUpdateContexts( revision ) ); - entityName = entity.getEntityMetamodel().getSuperclass(); + entityName = entity.getEntityMappingType().getSuperMappingType().getEntityName(); auditEntityName = configuration.getAuditEntityName( entityName ); entity = getQueryable( entityName, session ); }