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();
}
default Set<String> getSubclassEntityNames() {
return getEntityPersister().getEntityMetamodel().getSubclassEntityNames();
}
AttributeMapping findDeclaredAttributeMapping(String name);
/**

View File

@ -21,6 +21,7 @@ import org.hibernate.mapping.Collection;
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.FetchParent;
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 class 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<String> 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 class EntityCollectionPart
else {
ToOneAttributeMapping.addPrefixedPropertyNames(
targetKeyPropertyNames,
identifierProperty.getName(),
entityBinding.getIdentifierProperty().getName(),
propertyType,
creationProcess.getCreationContext().getSessionFactory()
);
@ -162,9 +163,7 @@ public class EntityCollectionPart
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 ) {

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.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 @@ public class ToOneAttributeMapping
if ( referencedPropertyName == null ) {
final Set<String> 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 @@ public class ToOneAttributeMapping
}
}
else {
this.targetKeyPropertyName = identifierProperty.getName();
this.targetKeyPropertyName = entityBinding.getIdentifierProperty().getName();
addPrefixedPropertyNames(
targetKeyPropertyNames,
targetKeyPropertyName,
@ -419,9 +415,9 @@ public class ToOneAttributeMapping
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 @@ public class ToOneAttributeMapping
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()
)
);
}
}

View File

@ -26,9 +26,7 @@ import java.util.Map;
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.AttributeMapping;
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.NonAggregatedIdentifierMapping;
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.InFlightEntityMappingType;
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 @@ 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;
@Override
@ -2441,27 +2468,38 @@ public abstract class AbstractEntityPersister
if ( attributeNames == null || attributeNames.length == 0 ) {
return ArrayHelper.EMPTY_INT_ARRAY;
}
int[] fields = new int[attributeNames.length];
int counter = 0;
final List<Integer> 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 abstract class AbstractEntityPersister
} );
}
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 abstract class AbstractEntityPersister
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 abstract class AbstractEntityPersister
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
public String generateFilterConditionAlias(String rootAlias) {
return rootAlias;
@ -6031,7 +6082,7 @@ public abstract class AbstractEntityPersister
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 );

View File

@ -40,14 +40,26 @@ import org.hibernate.mapping.Selectable;
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 class JoinedSubclassEntityPersister extends AbstractEntityPersister {
// PROPERTIES
int hydrateSpan = getPropertySpan();
naturalOrderPropertyTableNumbers = new int[hydrateSpan];
propertyTableNumbers = new int[hydrateSpan];
// propertyTableNumbers = new int[hydrateSpan];
List<Property> 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 class JoinedSubclassEntityPersister extends AbstractEntityPersister {
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
public String generateFilterConditionAlias(String rootAlias) {
return generateTableAlias( rootAlias, tableSpan - 1 );
@ -999,15 +1001,6 @@ public class JoinedSubclassEntityPersister extends AbstractEntityPersister {
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;

View File

@ -37,6 +37,7 @@ import org.hibernate.mapping.Selectable;
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 class SingleTableEntityPersister extends AbstractEntityPersister {
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() {
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
public String getSubclassPropertyTableName(int i) {
return subclassTableNameClosure[subclassPropertyTableNumberClosure[i]];
@ -715,12 +636,6 @@ public class SingleTableEntityPersister extends AbstractEntityPersister {
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 @@ public class SingleTableEntityPersister extends AbstractEntityPersister {
@Override
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
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(
"(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;
}
@Override
protected String filterFragment(String name) {
return hasWhere() ? getSQLWhereString( name ) : "";
}
@Override
protected String filterFragment(String alias, Set<String> treatAsDeclarations) {
return filterFragment( alias );
}
@Override
public String getSubclassPropertyTableName(int i) {
return getTableName();//ie. the subquery! yuck!
@ -524,7 +514,7 @@ public class UnionSubclassEntityPersister extends AbstractEntityPersister {
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 @@ public class UnionSubclassEntityPersister extends AbstractEntityPersister {
return true;
}
@Override
public String getPropertyTableName(String propertyName) {
//TODO: check this....
return getTableName();
}
@Override
public String[] getConstraintOrderedTableNameClosure() {
return constraintOrderedTableNames;

View File

@ -3989,7 +3989,7 @@ public abstract class BaseSqmToSqlAstConverter<T extends Statement> extends Base
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 @@ public abstract class BaseSqmToSqlAstConverter<T extends Statement> extends Base
.getRuntimeMetamodels()
.getMappingMetamodel();
final EntityPersister entityDescriptor = domainModel.findEntityDescriptor( treatTarget.getHibernateEntityName() );
final Set<String> subclassEntityNames = entityDescriptor.getEntityMetamodel().getSubclassEntityNames();
final Set<String> subclassEntityNames = entityDescriptor.getSubclassEntityNames();
return createTreatTypeRestriction( lhs, subclassEntityNames );
}

View File

@ -91,7 +91,7 @@ public abstract class AbstractCollectionInitializer implements CollectionInitial
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;
}
}

View File

@ -157,7 +157,7 @@ public class BatchEntitySelectFetchInitializer extends AbstractFetchParentAccess
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;
}
}

View File

@ -178,7 +178,7 @@ public class EntityDelayedFetchInitializer extends AbstractFetchParentAccess imp
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;
}
}

View File

@ -218,7 +218,7 @@ public class EntitySelectFetchInitializer extends AbstractFetchParentAccess impl
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;
}
}

View File

@ -11,7 +11,7 @@ import org.hibernate.type.Type;
/**
* @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 @@ public abstract class AbstractAttribute implements Attribute, Property {
this.attributeType = attributeType;
}
@Override
public String getNode() {
return null;
}
@Override
public String getName() {
return attributeName;

View File

@ -11,7 +11,7 @@ import org.hibernate.id.IdentifierGenerator;
/**
* @author Steve Ebersole
*/
public interface IdentifierAttribute extends Attribute, Property {
public interface IdentifierAttribute extends Attribute {
boolean isVirtual();
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
)
);
entityName = entity.getEntityMetamodel().getSuperclass();
entityName = entity.getEntityMappingType().getSuperMappingType().getEntityName();
auditEntityName = configuration.getAuditEntityName( entityName );
entity = getQueryable( entityName, session );
}