Get rid of some `getEntityMetamodel` uses

This commit is contained in:
Christian Beikov 2022-02-14 14:05:26 +01:00
parent 87638a9a2e
commit 260c738a5a
17 changed files with 180 additions and 373 deletions

View File

@ -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 <http://www.gnu.org/licenses/lgpl-2.1.html>.
*/
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() {
}
}

View File

@ -170,6 +170,10 @@ public interface EntityMappingType extends ManagedMappingType, EntityValuedModel
return getEntityPersister().getEntityMetamodel().hasSubclasses(); return getEntityPersister().getEntityMetamodel().hasSubclasses();
} }
default Set<String> getSubclassEntityNames() {
return getEntityPersister().getEntityMetamodel().getSubclassEntityNames();
}
AttributeMapping findDeclaredAttributeMapping(String name); AttributeMapping findDeclaredAttributeMapping(String name);
/** /**

View File

@ -21,6 +21,7 @@ import org.hibernate.mapping.Collection;
import org.hibernate.mapping.IndexedCollection; import org.hibernate.mapping.IndexedCollection;
import org.hibernate.mapping.Map; import org.hibernate.mapping.Map;
import org.hibernate.mapping.OneToMany; import org.hibernate.mapping.OneToMany;
import org.hibernate.mapping.PersistentClass;
import org.hibernate.mapping.SimpleValue; import org.hibernate.mapping.SimpleValue;
import org.hibernate.mapping.ToOne; import org.hibernate.mapping.ToOne;
import org.hibernate.mapping.Value; import org.hibernate.mapping.Value;
@ -66,8 +67,6 @@ import org.hibernate.sql.results.graph.FetchParent;
import org.hibernate.sql.results.graph.entity.EntityFetch; import org.hibernate.sql.results.graph.entity.EntityFetch;
import org.hibernate.sql.results.graph.entity.EntityValuedFetchable; import org.hibernate.sql.results.graph.entity.EntityValuedFetchable;
import org.hibernate.sql.results.graph.entity.internal.EntityFetchJoinedImpl; 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.CompositeType;
import org.hibernate.type.EntityType; import org.hibernate.type.EntityType;
import org.hibernate.type.Type; import org.hibernate.type.Type;
@ -98,24 +97,26 @@ public class EntityCollectionPart
this.nature = nature; this.nature = nature;
this.entityMappingType = entityMappingType; this.entityMappingType = entityMappingType;
final String referencedPropertyName; final String referencedPropertyName;
final PersistentClass entityBinding;
if ( bootModelValue instanceof OneToMany ) { if ( bootModelValue instanceof OneToMany ) {
final String mappedByProperty = collectionDescriptor.getMappedByProperty(); final String mappedByProperty = collectionDescriptor.getMappedByProperty();
referencedPropertyName = mappedByProperty == null || mappedByProperty.isEmpty() referencedPropertyName = mappedByProperty == null || mappedByProperty.isEmpty()
? null ? null
: mappedByProperty; : mappedByProperty;
entityBinding = ( (OneToMany) bootModelValue ).getBuildingContext().getMetadataCollector()
.getEntityBinding( entityMappingType.getEntityName() );
} }
else { else {
referencedPropertyName = ( (ToOne) bootModelValue ).getReferencedPropertyName(); final ToOne toOne = (ToOne) bootModelValue;
referencedPropertyName = toOne.getReferencedPropertyName();
entityBinding = toOne.getBuildingContext().getMetadataCollector()
.getEntityBinding( entityMappingType.getEntityName() );
} }
if ( referencedPropertyName == null ) { if ( referencedPropertyName == null ) {
final Set<String> targetKeyPropertyNames = new HashSet<>( 2 ); final Set<String> targetKeyPropertyNames = new HashSet<>( 2 );
targetKeyPropertyNames.add( EntityIdentifierMapping.ROLE_LOCAL_NAME ); targetKeyPropertyNames.add( EntityIdentifierMapping.ROLE_LOCAL_NAME );
final IdentifierProperty identifierProperty = getEntityMappingType() final Type propertyType = entityBinding.getIdentifier().getType();
.getEntityPersister() if ( entityBinding.getIdentifierProperty() == null ) {
.getEntityMetamodel()
.getIdentifierProperty();
final Type propertyType = identifierProperty.getType();
if ( identifierProperty.getName() == null ) {
final CompositeType compositeType; final CompositeType compositeType;
if ( propertyType.isComponentType() && ( compositeType = (CompositeType) propertyType ).isEmbedded() if ( propertyType.isComponentType() && ( compositeType = (CompositeType) propertyType ).isEmbedded()
&& compositeType.getPropertyNames().length == 1 ) { && compositeType.getPropertyNames().length == 1 ) {
@ -138,7 +139,7 @@ public class EntityCollectionPart
else { else {
ToOneAttributeMapping.addPrefixedPropertyNames( ToOneAttributeMapping.addPrefixedPropertyNames(
targetKeyPropertyNames, targetKeyPropertyNames,
identifierProperty.getName(), entityBinding.getIdentifierProperty().getName(),
propertyType, propertyType,
creationProcess.getCreationContext().getSessionFactory() creationProcess.getCreationContext().getSessionFactory()
); );
@ -162,9 +163,7 @@ public class EntityCollectionPart
this.targetKeyPropertyNames = targetKeyPropertyNames; this.targetKeyPropertyNames = targetKeyPropertyNames;
} }
else { else {
final EntityMetamodel entityMetamodel = entityMappingType.getEntityPersister().getEntityMetamodel(); final Type propertyType = entityBinding.getProperty( referencedPropertyName ).getType();
final int propertyIndex = entityMetamodel.getPropertyIndex( referencedPropertyName );
final Type propertyType = entityMetamodel.getPropertyTypes()[propertyIndex];
final CompositeType compositeType; final CompositeType compositeType;
if ( propertyType.isComponentType() && ( compositeType = (CompositeType) propertyType ).isEmbedded() if ( propertyType.isComponentType() && ( compositeType = (CompositeType) propertyType ).isEmbedded()
&& compositeType.getPropertyNames().length == 1 ) { && compositeType.getPropertyNames().length == 1 ) {

View File

@ -91,8 +91,6 @@ import org.hibernate.sql.results.graph.entity.internal.EntityResultImpl;
import org.hibernate.sql.results.graph.entity.internal.EntityResultJoinedSubclassImpl; import org.hibernate.sql.results.graph.entity.internal.EntityResultJoinedSubclassImpl;
import org.hibernate.sql.results.internal.domain.CircularBiDirectionalFetchImpl; import org.hibernate.sql.results.internal.domain.CircularBiDirectionalFetchImpl;
import org.hibernate.sql.results.internal.domain.CircularFetchImpl; 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.ComponentType;
import org.hibernate.type.CompositeType; import org.hibernate.type.CompositeType;
import org.hibernate.type.EmbeddedComponentType; import org.hibernate.type.EmbeddedComponentType;
@ -363,12 +361,10 @@ public class ToOneAttributeMapping
if ( referencedPropertyName == null ) { if ( referencedPropertyName == null ) {
final Set<String> targetKeyPropertyNames = new HashSet<>( 2 ); final Set<String> targetKeyPropertyNames = new HashSet<>( 2 );
targetKeyPropertyNames.add( EntityIdentifierMapping.ROLE_LOCAL_NAME ); targetKeyPropertyNames.add( EntityIdentifierMapping.ROLE_LOCAL_NAME );
final IdentifierProperty identifierProperty = getEntityMappingType() final PersistentClass entityBinding = bootValue.getBuildingContext().getMetadataCollector()
.getEntityPersister() .getEntityBinding( entityMappingType.getEntityName() );
.getEntityMetamodel() final Type propertyType = entityBinding.getIdentifier().getType();
.getIdentifierProperty(); if ( entityBinding.getIdentifierProperty() == null ) {
final Type propertyType = identifierProperty.getType();
if ( identifierProperty.getName() == null ) {
final CompositeType compositeType; final CompositeType compositeType;
if ( propertyType.isComponentType() && ( compositeType = (CompositeType) propertyType ).isEmbedded() if ( propertyType.isComponentType() && ( compositeType = (CompositeType) propertyType ).isEmbedded()
&& compositeType.getPropertyNames().length == 1 ) { && compositeType.getPropertyNames().length == 1 ) {
@ -397,7 +393,7 @@ public class ToOneAttributeMapping
} }
} }
else { else {
this.targetKeyPropertyName = identifierProperty.getName(); this.targetKeyPropertyName = entityBinding.getIdentifierProperty().getName();
addPrefixedPropertyNames( addPrefixedPropertyNames(
targetKeyPropertyNames, targetKeyPropertyNames,
targetKeyPropertyName, targetKeyPropertyName,
@ -419,9 +415,9 @@ public class ToOneAttributeMapping
this.targetKeyPropertyNames = targetKeyPropertyNames; this.targetKeyPropertyNames = targetKeyPropertyNames;
} }
else { else {
final EntityMetamodel entityMetamodel = entityMappingType.getEntityPersister().getEntityMetamodel(); final PersistentClass entityBinding = bootValue.getBuildingContext().getMetadataCollector()
final int propertyIndex = entityMetamodel.getPropertyIndex( referencedPropertyName ); .getEntityBinding( entityMappingType.getEntityName() );
final Type propertyType = entityMetamodel.getPropertyTypes()[propertyIndex]; final Type propertyType = entityBinding.getProperty( referencedPropertyName ).getType();
final CompositeType compositeType; final CompositeType compositeType;
if ( propertyType.isComponentType() && ( compositeType = (CompositeType) propertyType ).isEmbedded() if ( propertyType.isComponentType() && ( compositeType = (CompositeType) propertyType ).isEmbedded()
&& compositeType.getPropertyNames().length == 1 ) { && compositeType.getPropertyNames().length == 1 ) {
@ -1165,8 +1161,11 @@ public class ToOneAttributeMapping
else { else {
// case 1.1 // case 1.1
// Make sure the entity identifier is not a target key property i.e. this really is a unique key mapping // 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( return bidirectionalAttributeName != null && (
entityMappingType.getEntityPersister().getEntityMetamodel().getIdentifierProperty().getName() !( entityMappingType.getIdentifierMapping() instanceof SingleAttributeIdentifierMapping )
|| !targetKeyPropertyNames.contains(
( (SingleAttributeIdentifierMapping) entityMappingType.getIdentifierMapping() ).getAttributeName()
)
); );
} }
} }

View File

@ -26,9 +26,7 @@ import java.util.Map;
import java.util.Objects; import java.util.Objects;
import java.util.Set; import java.util.Set;
import java.util.SortedMap; import java.util.SortedMap;
import java.util.SortedSet;
import java.util.TreeMap; import java.util.TreeMap;
import java.util.TreeSet;
import java.util.function.BiConsumer; import java.util.function.BiConsumer;
import java.util.function.Consumer; import java.util.function.Consumer;
import java.util.function.Supplier; import java.util.function.Supplier;
@ -156,6 +154,7 @@ import org.hibernate.metamodel.mapping.AttributeMapping;
import org.hibernate.metamodel.mapping.AttributeMetadata; import org.hibernate.metamodel.mapping.AttributeMetadata;
import org.hibernate.metamodel.mapping.AttributeMetadataAccess; import org.hibernate.metamodel.mapping.AttributeMetadataAccess;
import org.hibernate.metamodel.mapping.BasicValuedModelPart; import org.hibernate.metamodel.mapping.BasicValuedModelPart;
import org.hibernate.metamodel.mapping.DiscriminatedAssociationModelPart;
import org.hibernate.metamodel.mapping.EmbeddableValuedModelPart; import org.hibernate.metamodel.mapping.EmbeddableValuedModelPart;
import org.hibernate.metamodel.mapping.EntityDiscriminatorMapping; import org.hibernate.metamodel.mapping.EntityDiscriminatorMapping;
import org.hibernate.metamodel.mapping.EntityIdentifierMapping; import org.hibernate.metamodel.mapping.EntityIdentifierMapping;
@ -172,6 +171,7 @@ import org.hibernate.metamodel.mapping.NonAggregatedIdentifierMapping;
import org.hibernate.metamodel.mapping.PluralAttributeMapping; import org.hibernate.metamodel.mapping.PluralAttributeMapping;
import org.hibernate.metamodel.mapping.Queryable; import org.hibernate.metamodel.mapping.Queryable;
import org.hibernate.metamodel.mapping.SelectableConsumer; import org.hibernate.metamodel.mapping.SelectableConsumer;
import org.hibernate.metamodel.mapping.SelectableMapping;
import org.hibernate.metamodel.mapping.SingularAttributeMapping; import org.hibernate.metamodel.mapping.SingularAttributeMapping;
import org.hibernate.metamodel.mapping.StateArrayContributorMapping; import org.hibernate.metamodel.mapping.StateArrayContributorMapping;
import org.hibernate.metamodel.mapping.StateArrayContributorMetadata; import org.hibernate.metamodel.mapping.StateArrayContributorMetadata;
@ -188,6 +188,7 @@ import org.hibernate.metamodel.mapping.internal.InFlightEntityMappingType;
import org.hibernate.metamodel.mapping.internal.MappingModelCreationHelper; import org.hibernate.metamodel.mapping.internal.MappingModelCreationHelper;
import org.hibernate.metamodel.mapping.internal.MappingModelCreationProcess; import org.hibernate.metamodel.mapping.internal.MappingModelCreationProcess;
import org.hibernate.metamodel.mapping.internal.SimpleNaturalIdMapping; 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.model.domain.NavigableRole;
import org.hibernate.metamodel.spi.EntityInstantiator; import org.hibernate.metamodel.spi.EntityInstantiator;
import org.hibernate.metamodel.spi.EntityRepresentationStrategy; import org.hibernate.metamodel.spi.EntityRepresentationStrategy;
@ -2313,6 +2314,32 @@ public abstract class AbstractEntityPersister
} }
} }
@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; private DiscriminatorMetadata discriminatorMetadata;
@Override @Override
@ -2441,27 +2468,38 @@ public abstract class AbstractEntityPersister
if ( attributeNames == null || attributeNames.length == 0 ) { if ( attributeNames == null || attributeNames.length == 0 ) {
return ArrayHelper.EMPTY_INT_ARRAY; return ArrayHelper.EMPTY_INT_ARRAY;
} }
int[] fields = new int[attributeNames.length]; final List<Integer> fields = new ArrayList<>( attributeNames.length );
int counter = 0;
// We sort to get rid of duplicates // Sort attribute names so that we can traverse mappings efficiently
Arrays.sort( attributeNames ); Arrays.sort( attributeNames );
Integer index0 = entityMetamodel.getPropertyIndexOrNull( attributeNames[0] ); int index = 0;
if ( index0 != null ) { for ( final AttributeMapping attributeMapping : attributeMappings ) {
fields[counter++] = index0; 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 {
for ( int i = 0, j = 1; j < attributeNames.length; ++i, ++j ) { break;
if ( !attributeNames[i].equals( attributeNames[j] ) ) { }
Integer index = entityMetamodel.getPropertyIndexOrNull( attributeNames[j] ); } while ( index < attributeNames.length );
if ( index != null ) { }
fields[counter++] = index; else {
break;
} }
} }
} }
return Arrays.copyOf( fields, counter ); return ArrayHelper.toIntArray( fields );
} }
@Override @Override
@ -2498,11 +2536,38 @@ public abstract class AbstractEntityPersister
} ); } );
} }
if ( attributeNames.length != 0 ) {
final boolean[] propertyUpdateability = entityMetamodel.getPropertyUpdateability(); final boolean[] propertyUpdateability = entityMetamodel.getPropertyUpdateability();
for ( String attributeName : attributeNames ) {
final Integer index = entityMetamodel.getPropertyIndexOrNull( attributeName ); // Sort attribute names so that we can traverse mappings efficiently
if ( index != null && propertyUpdateability[index] && !fields.contains( index ) ) { Arrays.sort( attributeNames );
fields.add( index ); 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 abstract class AbstractEntityPersister
return entityMetamodel.getPropertyIndex( 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 { private void initOrdinaryPropertyPaths(Metadata mapping) throws MappingException {
for ( int i = 0; i < getSubclassPropertyNameClosure().length; i++ ) { for ( int i = 0; i < getSubclassPropertyNameClosure().length; i++ ) {
propertyMapping.initPropertyPaths( propertyMapping.initPropertyPaths(
@ -4003,12 +4060,6 @@ public abstract class AbstractEntityPersister
predicateConsumer.accept( new SqlFragmentPredicate( fragment ) ); predicateConsumer.accept( new SqlFragmentPredicate( fragment ) );
} }
protected String filterFragment(String alias) throws MappingException {
return filterFragment( alias, Collections.emptySet() );
}
protected abstract String filterFragment(String alias, Set<String> treatAsDeclarations);
@Override @Override
public String generateFilterConditionAlias(String rootAlias) { public String generateFilterConditionAlias(String rootAlias) {
return rootAlias; return rootAlias;
@ -6031,7 +6082,7 @@ public abstract class AbstractEntityPersister
final int propertyIndex = getPropertyIndex( bootProperty.getName() ); final int propertyIndex = getPropertyIndex( bootProperty.getName() );
final String tableExpression = getPropertyTableName( attrName ); final String tableExpression = getTableName( getPropertyTableNumbers()[propertyIndex] );
final String[] attrColumnNames = getPropertyColumnNames( propertyIndex ); final String[] attrColumnNames = getPropertyColumnNames( propertyIndex );
final PropertyAccess propertyAccess = getRepresentationStrategy().resolvePropertyAccess( bootProperty ); final PropertyAccess propertyAccess = getRepresentationStrategy().resolvePropertyAccess( bootProperty );

View File

@ -40,14 +40,26 @@ import org.hibernate.mapping.Selectable;
import org.hibernate.mapping.Subclass; import org.hibernate.mapping.Subclass;
import org.hibernate.mapping.Table; import org.hibernate.mapping.Table;
import org.hibernate.mapping.Value; 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.EntityDiscriminatorMapping;
import org.hibernate.metamodel.mapping.EntityIdentifierMapping; import org.hibernate.metamodel.mapping.EntityIdentifierMapping;
import org.hibernate.metamodel.mapping.EntityMappingType; import org.hibernate.metamodel.mapping.EntityMappingType;
import org.hibernate.metamodel.mapping.EntityVersionMapping; 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.BasicEntityIdentifierMappingImpl;
import org.hibernate.metamodel.mapping.internal.CaseStatementDiscriminatorMappingImpl; 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.MappingModelCreationHelper;
import org.hibernate.metamodel.mapping.internal.MappingModelCreationProcess; 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.MappingMetamodelImplementor;
import org.hibernate.metamodel.spi.RuntimeModelCreationContext; import org.hibernate.metamodel.spi.RuntimeModelCreationContext;
import org.hibernate.persister.spi.PersisterCreationContext; import org.hibernate.persister.spi.PersisterCreationContext;
@ -108,7 +120,7 @@ public class JoinedSubclassEntityPersister extends AbstractEntityPersister {
// properties of this class, including inherited properties // properties of this class, including inherited properties
private final int[] naturalOrderPropertyTableNumbers; private final int[] naturalOrderPropertyTableNumbers;
private final int[] propertyTableNumbers; // private final int[] propertyTableNumbers;
// the closure of all properties in the entire hierarchy including // the closure of all properties in the entire hierarchy including
// subclasses and superclasses of this class // subclasses and superclasses of this class
@ -446,13 +458,13 @@ public class JoinedSubclassEntityPersister extends AbstractEntityPersister {
// PROPERTIES // PROPERTIES
int hydrateSpan = getPropertySpan(); int hydrateSpan = getPropertySpan();
naturalOrderPropertyTableNumbers = new int[hydrateSpan]; naturalOrderPropertyTableNumbers = new int[hydrateSpan];
propertyTableNumbers = new int[hydrateSpan]; // propertyTableNumbers = new int[hydrateSpan];
List<Property> propertyClosure = persistentClass.getPropertyClosure(); List<Property> propertyClosure = persistentClass.getPropertyClosure();
for ( int i = 0; i < propertyClosure.size(); i++ ) { for ( int i = 0; i < propertyClosure.size(); i++ ) {
String tableName = propertyClosure.get(i).getValue().getTable().getQualifiedName( String tableName = propertyClosure.get(i).getValue().getTable().getQualifiedName(
factory.getSqlStringGenerationContext() factory.getSqlStringGenerationContext()
); );
propertyTableNumbers[i] = getTableId( tableName, this.tableNames ); // propertyTableNumbers[i] = getTableId( tableName, this.tableNames );
naturalOrderPropertyTableNumbers[i] = getTableId( tableName, naturalOrderTableNames ); naturalOrderPropertyTableNumbers[i] = getTableId( tableName, naturalOrderTableNames );
} }
@ -879,16 +891,6 @@ public class JoinedSubclassEntityPersister extends AbstractEntityPersister {
return tableNames[0]; return tableNames[0];
} }
@Override
protected String filterFragment(String alias) {
return hasWhere() ? getSQLWhereString( generateFilterConditionAlias( alias ) ) : "";
}
@Override
protected String filterFragment(String alias, Set<String> treatAsDeclarations) {
return filterFragment( alias );
}
@Override @Override
public String generateFilterConditionAlias(String rootAlias) { public String generateFilterConditionAlias(String rootAlias) {
return generateTableAlias( rootAlias, tableSpan - 1 ); return generateTableAlias( rootAlias, tableSpan - 1 );
@ -999,15 +1001,6 @@ public class JoinedSubclassEntityPersister extends AbstractEntityPersister {
return subclassNamesBySubclassTable[index]; return subclassNamesBySubclassTable[index];
} }
@Override
public String getPropertyTableName(String propertyName) {
Integer index = getEntityMetamodel().getPropertyIndexOrNull( propertyName );
if ( index == null ) {
return null;
}
return tableNames[propertyTableNumbers[index]];
}
@Override @Override
public String[] getConstraintOrderedTableNameClosure() { public String[] getConstraintOrderedTableNameClosure() {
return constraintOrderedTableNames; return constraintOrderedTableNames;

View File

@ -37,6 +37,7 @@ import org.hibernate.mapping.Selectable;
import org.hibernate.mapping.Subclass; import org.hibernate.mapping.Subclass;
import org.hibernate.mapping.Table; import org.hibernate.mapping.Table;
import org.hibernate.mapping.Value; import org.hibernate.mapping.Value;
import org.hibernate.metamodel.spi.MappingMetamodelImplementor;
import org.hibernate.metamodel.spi.RuntimeModelCreationContext; import org.hibernate.metamodel.spi.RuntimeModelCreationContext;
import org.hibernate.persister.spi.PersisterCreationContext; import org.hibernate.persister.spi.PersisterCreationContext;
import org.hibernate.query.sqm.ComparisonOperator; import org.hibernate.query.sqm.ComparisonOperator;
@ -562,90 +563,10 @@ public class SingleTableEntityPersister extends AbstractEntityPersister {
return getTableName() + ' ' + 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<String> 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<String> 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() { private boolean needsDiscriminator() {
return forceDiscriminator || isInherited(); return forceDiscriminator || isInherited();
} }
private String[] decodeTreatAsRequests(Set<String> treatAsDeclarations) {
final List<String> 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<String> 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 @Override
public String getSubclassPropertyTableName(int i) { public String getSubclassPropertyTableName(int i) {
return subclassTableNameClosure[subclassPropertyTableNumberClosure[i]]; return subclassTableNameClosure[subclassPropertyTableNumberClosure[i]];
@ -715,12 +636,6 @@ public class SingleTableEntityPersister extends AbstractEntityPersister {
return isNullableSubclassTable[j]; return isNullableSubclassTable[j];
} }
@Override
public String getPropertyTableName(String propertyName) {
Integer index = getEntityMetamodel().getPropertyIndexOrNull( propertyName );
return index == null ? null : qualifiedTableNames[propertyTableNumbers[index]];
}
@Override @Override
protected boolean hasMultipleTables() { protected boolean hasMultipleTables() {
return getTableSpan() > 1; return getTableSpan() > 1;
@ -880,10 +795,47 @@ public class SingleTableEntityPersister extends AbstractEntityPersister {
@Override @Override
public void pruneForSubclasses(TableGroup tableGroup, Set<String> treatedEntityNames) { public void pruneForSubclasses(TableGroup tableGroup, Set<String> treatedEntityNames) {
if ( !needsDiscriminator() && treatedEntityNames.isEmpty() ) {
return;
}
// The optimization is to simply add the discriminator filter fragment for all treated entity names // The optimization is to simply add the discriminator filter fragment for all treated entity names
final NamedTableReference tableReference = (NamedTableReference) tableGroup.getPrimaryTableReference(); 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<String> 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( tableReference.setPrunedTableExpression(
"(select * from " + getTableName() + " t where " + discriminatorFilterFragment( "t", treatedEntityNames ) + ")" "(select * from " + getTableName() + " t where " + frag.toFragmentString() + ")"
); );
} }

View File

@ -351,16 +351,6 @@ public class UnionSubclassEntityPersister extends AbstractEntityPersister {
return getTableName() + ' ' + name; return getTableName() + ' ' + name;
} }
@Override
protected String filterFragment(String name) {
return hasWhere() ? getSQLWhereString( name ) : "";
}
@Override
protected String filterFragment(String alias, Set<String> treatAsDeclarations) {
return filterFragment( alias );
}
@Override @Override
public String getSubclassPropertyTableName(int i) { public String getSubclassPropertyTableName(int i) {
return getTableName();//ie. the subquery! yuck! return getTableName();//ie. the subquery! yuck!
@ -524,7 +514,7 @@ public class UnionSubclassEntityPersister extends AbstractEntityPersister {
final StringBuilder buf = new StringBuilder( subquery.length() ) final StringBuilder buf = new StringBuilder( subquery.length() )
.append( "( " ); .append( "( " );
for ( String name : getEntityMetamodel().getSubclassEntityNames() ) { for ( String name : getSubclassEntityNames() ) {
final AbstractEntityPersister persister = (AbstractEntityPersister) metamodel.findEntityDescriptor( name ); final AbstractEntityPersister persister = (AbstractEntityPersister) metamodel.findEntityDescriptor( name );
final String subclassTableName = persister.getTableName(); final String subclassTableName = persister.getTableName();
if ( treatedTableNames.contains( subclassTableName ) ) { if ( treatedTableNames.contains( subclassTableName ) ) {
@ -595,12 +585,6 @@ public class UnionSubclassEntityPersister extends AbstractEntityPersister {
return true; return true;
} }
@Override
public String getPropertyTableName(String propertyName) {
//TODO: check this....
return getTableName();
}
@Override @Override
public String[] getConstraintOrderedTableNameClosure() { public String[] getConstraintOrderedTableNameClosure() {
return constraintOrderedTableNames; return constraintOrderedTableNames;

View File

@ -3989,7 +3989,7 @@ public abstract class BaseSqmToSqlAstConverter<T extends Statement> extends Base
treatedPath.getTreatTarget().getHibernateEntityName() treatedPath.getTreatTarget().getHibernateEntityName()
); );
conjunctTreatUsages.computeIfAbsent( treatedPath.getWrappedPath(), p -> new HashSet<>( 1 ) ) conjunctTreatUsages.computeIfAbsent( treatedPath.getWrappedPath(), p -> new HashSet<>( 1 ) )
.addAll( entityDescriptor.getEntityMetamodel().getSubclassEntityNames() ); .addAll( entityDescriptor.getSubclassEntityNames() );
return expression; return expression;
} }
// Note: If the columns that are accessed are not shared with other entities, we could avoid this wrapping // Note: If the columns that are accessed are not shared with other entities, we could avoid this wrapping
@ -4039,7 +4039,7 @@ public abstract class BaseSqmToSqlAstConverter<T extends Statement> extends Base
.getRuntimeMetamodels() .getRuntimeMetamodels()
.getMappingMetamodel(); .getMappingMetamodel();
final EntityPersister entityDescriptor = domainModel.findEntityDescriptor( treatTarget.getHibernateEntityName() ); final EntityPersister entityDescriptor = domainModel.findEntityDescriptor( treatTarget.getHibernateEntityName() );
final Set<String> subclassEntityNames = entityDescriptor.getEntityMetamodel().getSubclassEntityNames(); final Set<String> subclassEntityNames = entityDescriptor.getSubclassEntityNames();
return createTreatTypeRestriction( lhs, subclassEntityNames ); return createTreatTypeRestriction( lhs, subclassEntityNames );
} }

View File

@ -91,7 +91,7 @@ public abstract class AbstractCollectionInitializer implements CollectionInitial
if ( concreteDescriptor.isPolymorphic() ) { if ( concreteDescriptor.isPolymorphic() ) {
final AbstractEntityPersister declaringType = (AbstractEntityPersister) collectionAttributeMapping.getDeclaringType(); final AbstractEntityPersister declaringType = (AbstractEntityPersister) collectionAttributeMapping.getDeclaringType();
if ( concreteDescriptor != declaringType ) { if ( concreteDescriptor != declaringType ) {
if ( !declaringType.getEntityMetamodel().getSubclassEntityNames().contains( concreteDescriptor.getEntityMetamodel().getName() ) ) { if ( !declaringType.getSubclassEntityNames().contains( concreteDescriptor.getName() ) ) {
return false; return false;
} }
} }

View File

@ -157,7 +157,7 @@ public class BatchEntitySelectFetchInitializer extends AbstractFetchParentAccess
if ( concreteDescriptor.isPolymorphic() ) { if ( concreteDescriptor.isPolymorphic() ) {
final AbstractEntityPersister declaringType = (AbstractEntityPersister) referencedModelPart.getDeclaringType(); final AbstractEntityPersister declaringType = (AbstractEntityPersister) referencedModelPart.getDeclaringType();
if ( concreteDescriptor != declaringType ) { if ( concreteDescriptor != declaringType ) {
if ( !declaringType.getEntityMetamodel().getSubclassEntityNames().contains( concreteDescriptor.getEntityMetamodel().getName() ) ) { if ( !declaringType.getSubclassEntityNames().contains( concreteDescriptor.getName() ) ) {
return false; return false;
} }
} }

View File

@ -178,7 +178,7 @@ public class EntityDelayedFetchInitializer extends AbstractFetchParentAccess imp
if ( concreteDescriptor.isPolymorphic() ) { if ( concreteDescriptor.isPolymorphic() ) {
final AbstractEntityPersister declaringType = (AbstractEntityPersister) referencedModelPart.getDeclaringType(); final AbstractEntityPersister declaringType = (AbstractEntityPersister) referencedModelPart.getDeclaringType();
if ( concreteDescriptor != declaringType ) { if ( concreteDescriptor != declaringType ) {
if ( !declaringType.getEntityMetamodel().getSubclassEntityNames().contains( concreteDescriptor.getEntityMetamodel().getName() ) ) { if ( !declaringType.getSubclassEntityNames().contains( concreteDescriptor.getName() ) ) {
return false; return false;
} }
} }

View File

@ -218,7 +218,7 @@ public class EntitySelectFetchInitializer extends AbstractFetchParentAccess impl
if ( concreteDescriptor.isPolymorphic() ) { if ( concreteDescriptor.isPolymorphic() ) {
final AbstractEntityPersister declaringType = (AbstractEntityPersister) referencedModelPart.getDeclaringType(); final AbstractEntityPersister declaringType = (AbstractEntityPersister) referencedModelPart.getDeclaringType();
if ( concreteDescriptor != declaringType ) { if ( concreteDescriptor != declaringType ) {
if ( !declaringType.getEntityMetamodel().getSubclassEntityNames().contains( concreteDescriptor.getEntityMetamodel().getName() ) ) { if ( !declaringType.getSubclassEntityNames().contains( concreteDescriptor.getName() ) ) {
return false; return false;
} }
} }

View File

@ -11,7 +11,7 @@ import org.hibernate.type.Type;
/** /**
* @author Steve Ebersole * @author Steve Ebersole
*/ */
public abstract class AbstractAttribute implements Attribute, Property { public abstract class AbstractAttribute implements Attribute {
private final String attributeName; private final String attributeName;
private final Type attributeType; private final Type attributeType;
@ -20,11 +20,6 @@ public abstract class AbstractAttribute implements Attribute, Property {
this.attributeType = attributeType; this.attributeType = attributeType;
} }
@Override
public String getNode() {
return null;
}
@Override @Override
public String getName() { public String getName() {
return attributeName; return attributeName;

View File

@ -11,7 +11,7 @@ import org.hibernate.id.IdentifierGenerator;
/** /**
* @author Steve Ebersole * @author Steve Ebersole
*/ */
public interface IdentifierAttribute extends Attribute, Property { public interface IdentifierAttribute extends Attribute {
boolean isVirtual(); boolean isVirtual();
boolean isEmbedded(); boolean isEmbedded();

View File

@ -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 <http://www.gnu.org/licenses/lgpl-2.1.html>.
*/
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();
}

View File

@ -511,7 +511,7 @@ public class ValidityAuditStrategy implements AuditStrategy {
revision revision
) )
); );
entityName = entity.getEntityMetamodel().getSuperclass(); entityName = entity.getEntityMappingType().getSuperMappingType().getEntityName();
auditEntityName = configuration.getAuditEntityName( entityName ); auditEntityName = configuration.getAuditEntityName( entityName );
entity = getQueryable( entityName, session ); entity = getQueryable( entityName, session );
} }