Refactoring
This commit is contained in:
parent
3222b52ab2
commit
16d81eb4bf
|
@ -383,87 +383,7 @@ public class LoaderSelectBuilder {
|
|||
|
||||
final List<Fetch> fetches = new ArrayList<>();
|
||||
|
||||
final Consumer<Fetchable> processor = fetchable -> {
|
||||
final NavigablePath fetchablePath;
|
||||
final Fetchable fetchedFetchable;
|
||||
if ( fetchable instanceof PluralAttributeMapping ) {
|
||||
fetchablePath = fetchParent.getNavigablePath()
|
||||
.append( fetchable.getFetchableName() )
|
||||
.append( CollectionPart.Nature.ELEMENT.getName() );
|
||||
fetchedFetchable = ( (PluralAttributeMapping) fetchable ).getElementDescriptor();
|
||||
}
|
||||
else {
|
||||
fetchablePath = fetchParent.getNavigablePath().append( fetchable.getFetchableName() );
|
||||
fetchedFetchable = fetchable;
|
||||
}
|
||||
|
||||
final Fetch biDirectionalFetch = fetchedFetchable.resolveCircularFetch(
|
||||
fetchablePath,
|
||||
fetchParent,
|
||||
creationState
|
||||
);
|
||||
|
||||
if ( biDirectionalFetch != null ) {
|
||||
fetches.add( biDirectionalFetch );
|
||||
return;
|
||||
}
|
||||
|
||||
LockMode lockMode = LockMode.READ;
|
||||
FetchTiming fetchTiming = fetchable.getMappedFetchStrategy().getTiming();
|
||||
boolean joined = fetchable.getMappedFetchStrategy().getStyle() == FetchStyle.JOIN;
|
||||
|
||||
// if ( loadable instanceof PluralValuedNavigable ) {
|
||||
// // processing a collection-loader
|
||||
//
|
||||
// // if the `fetchable` is the "collection owner" and the collection owner is available in Session - don't join
|
||||
// final String collectionMappedByProperty = ( (PluralValuedNavigable) rootContainer ).getCollectionDescriptor()
|
||||
// .getMappedByProperty();
|
||||
// if ( collectionMappedByProperty != null && collectionMappedByProperty.equals( fetchable.getNavigableName() ) ) {
|
||||
// joined = false;
|
||||
// }
|
||||
// }
|
||||
|
||||
final Integer maximumFetchDepth = creationContext.getMaximumFetchDepth();
|
||||
|
||||
if ( maximumFetchDepth != null ) {
|
||||
if ( fetchDepth == maximumFetchDepth ) {
|
||||
joined = false;
|
||||
}
|
||||
else if ( fetchDepth > maximumFetchDepth ) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
if ( ! (fetchable instanceof BasicValuedModelPart) ) {
|
||||
fetchDepth++;
|
||||
}
|
||||
Fetch fetch = fetchedFetchable.generateFetch(
|
||||
fetchParent,
|
||||
fetchablePath,
|
||||
fetchTiming,
|
||||
joined,
|
||||
lockMode,
|
||||
null,
|
||||
creationState
|
||||
);
|
||||
fetches.add( fetch );
|
||||
|
||||
if ( fetchable instanceof PluralAttributeMapping && fetchTiming == FetchTiming.IMMEDIATE ) {
|
||||
applyOrdering(
|
||||
querySpec,
|
||||
fetchablePath,
|
||||
( (PluralAttributeMapping) fetchable ),
|
||||
creationState
|
||||
);
|
||||
}
|
||||
}
|
||||
finally {
|
||||
if ( ! (fetchable instanceof BasicValuedModelPart) ) {
|
||||
fetchDepth--;
|
||||
}
|
||||
}
|
||||
};
|
||||
final Consumer<Fetchable> processor = createFetchableConsumer( fetchParent, querySpec, creationState, fetches );
|
||||
|
||||
final FetchableContainer referencedMappingContainer = fetchParent.getReferencedMappingContainer();
|
||||
referencedMappingContainer.visitKeyFetchables( processor, null );
|
||||
|
@ -472,6 +392,93 @@ public class LoaderSelectBuilder {
|
|||
return fetches;
|
||||
}
|
||||
|
||||
private Consumer<Fetchable> createFetchableConsumer(
|
||||
FetchParent fetchParent,
|
||||
QuerySpec querySpec,
|
||||
LoaderSqlAstCreationState creationState, List<Fetch> fetches) {
|
||||
return fetchable -> {
|
||||
final NavigablePath fetchablePath;
|
||||
final Fetchable fetchedFetchable;
|
||||
if ( fetchable instanceof PluralAttributeMapping ) {
|
||||
fetchablePath = fetchParent.getNavigablePath()
|
||||
.append( fetchable.getFetchableName() )
|
||||
.append( CollectionPart.Nature.ELEMENT.getName() );
|
||||
fetchedFetchable = ( (PluralAttributeMapping) fetchable ).getElementDescriptor();
|
||||
}
|
||||
else {
|
||||
fetchablePath = fetchParent.getNavigablePath().append( fetchable.getFetchableName() );
|
||||
fetchedFetchable = fetchable;
|
||||
}
|
||||
|
||||
final Fetch biDirectionalFetch = fetchedFetchable.resolveCircularFetch(
|
||||
fetchablePath,
|
||||
fetchParent,
|
||||
creationState
|
||||
);
|
||||
|
||||
if ( biDirectionalFetch != null ) {
|
||||
fetches.add( biDirectionalFetch );
|
||||
return;
|
||||
}
|
||||
|
||||
LockMode lockMode = LockMode.READ;
|
||||
FetchTiming fetchTiming = fetchable.getMappedFetchStrategy().getTiming();
|
||||
boolean joined = fetchable.getMappedFetchStrategy().getStyle() == FetchStyle.JOIN;
|
||||
|
||||
// if ( loadable instanceof PluralValuedNavigable ) {
|
||||
// // processing a collection-loader
|
||||
//
|
||||
// // if the `fetchable` is the "collection owner" and the collection owner is available in Session - don't join
|
||||
// final String collectionMappedByProperty = ( (PluralValuedNavigable) rootContainer ).getCollectionDescriptor()
|
||||
// .getMappedByProperty();
|
||||
// if ( collectionMappedByProperty != null && collectionMappedByProperty.equals( fetchable.getNavigableName() ) ) {
|
||||
// joined = false;
|
||||
// }
|
||||
// }
|
||||
|
||||
final Integer maximumFetchDepth = creationContext.getMaximumFetchDepth();
|
||||
|
||||
if ( maximumFetchDepth != null ) {
|
||||
if ( fetchDepth == maximumFetchDepth ) {
|
||||
joined = false;
|
||||
}
|
||||
else if ( fetchDepth > maximumFetchDepth ) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
if ( ! (fetchable instanceof BasicValuedModelPart ) ) {
|
||||
fetchDepth++;
|
||||
}
|
||||
Fetch fetch = fetchedFetchable.generateFetch(
|
||||
fetchParent,
|
||||
fetchablePath,
|
||||
fetchTiming,
|
||||
joined,
|
||||
lockMode,
|
||||
null,
|
||||
creationState
|
||||
);
|
||||
fetches.add( fetch );
|
||||
|
||||
if ( fetchable instanceof PluralAttributeMapping && fetchTiming == FetchTiming.IMMEDIATE ) {
|
||||
applyOrdering(
|
||||
querySpec,
|
||||
fetchablePath,
|
||||
( (PluralAttributeMapping) fetchable ),
|
||||
creationState
|
||||
);
|
||||
}
|
||||
}
|
||||
finally {
|
||||
if ( ! (fetchable instanceof BasicValuedModelPart) ) {
|
||||
fetchDepth--;
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private void applyOrdering(
|
||||
QuerySpec ast,
|
||||
NavigablePath navigablePath,
|
||||
|
|
|
@ -0,0 +1,291 @@
|
|||
/*
|
||||
* 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.metamodel.mapping.internal;
|
||||
|
||||
import java.util.Locale;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import org.hibernate.LockMode;
|
||||
import org.hibernate.engine.FetchStrategy;
|
||||
import org.hibernate.engine.FetchTiming;
|
||||
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||
import org.hibernate.engine.spi.SharedSessionContractImplementor;
|
||||
import org.hibernate.mapping.PersistentClass;
|
||||
import org.hibernate.metamodel.mapping.BasicEntityIdentifierMapping;
|
||||
import org.hibernate.metamodel.mapping.BasicValuedMapping;
|
||||
import org.hibernate.metamodel.mapping.BasicValuedModelPart;
|
||||
import org.hibernate.metamodel.mapping.ColumnConsumer;
|
||||
import org.hibernate.metamodel.mapping.EntityIdentifierMapping;
|
||||
import org.hibernate.metamodel.mapping.EntityMappingType;
|
||||
import org.hibernate.metamodel.mapping.JdbcMapping;
|
||||
import org.hibernate.metamodel.mapping.MappingType;
|
||||
import org.hibernate.metamodel.model.convert.spi.BasicValueConverter;
|
||||
import org.hibernate.metamodel.model.domain.NavigableRole;
|
||||
import org.hibernate.persister.entity.EntityPersister;
|
||||
import org.hibernate.property.access.spi.PropertyAccess;
|
||||
import org.hibernate.query.NavigablePath;
|
||||
import org.hibernate.sql.ast.Clause;
|
||||
import org.hibernate.sql.ast.spi.SqlExpressionResolver;
|
||||
import org.hibernate.sql.ast.spi.SqlSelection;
|
||||
import org.hibernate.sql.ast.tree.expression.ColumnReference;
|
||||
import org.hibernate.sql.ast.tree.expression.Expression;
|
||||
import org.hibernate.sql.ast.tree.from.TableGroup;
|
||||
import org.hibernate.sql.ast.tree.from.TableReference;
|
||||
import org.hibernate.sql.results.graph.DomainResult;
|
||||
import org.hibernate.sql.results.graph.DomainResultCreationState;
|
||||
import org.hibernate.sql.results.graph.Fetch;
|
||||
import org.hibernate.sql.results.graph.FetchParent;
|
||||
import org.hibernate.sql.results.graph.basic.BasicFetch;
|
||||
import org.hibernate.sql.results.graph.basic.BasicResult;
|
||||
import org.hibernate.type.BasicType;
|
||||
import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
|
||||
import org.hibernate.type.spi.TypeConfiguration;
|
||||
|
||||
/**
|
||||
* @author Andrea Boriero
|
||||
*/
|
||||
public class BasicEntityIdentifierMappingImpl implements BasicEntityIdentifierMapping {
|
||||
private final PropertyAccess propertyAccess;
|
||||
private final EntityPersister entityPersister;
|
||||
private final SessionFactoryImplementor sessionFactory;
|
||||
private final NavigableRole idRole;
|
||||
private final String rootTable;
|
||||
private final String pkColumnName;
|
||||
private final BasicType idType;
|
||||
|
||||
public BasicEntityIdentifierMappingImpl(
|
||||
EntityPersister entityPersister,
|
||||
String rootTable,
|
||||
String pkColumnName,
|
||||
BasicType idType,
|
||||
MappingModelCreationProcess creationProcess
|
||||
) {
|
||||
assert entityPersister.hasIdentifierProperty();
|
||||
assert entityPersister.getIdentifierPropertyName() != null;
|
||||
this.rootTable = rootTable;
|
||||
this.pkColumnName = pkColumnName;
|
||||
this.idType = idType;
|
||||
this.entityPersister = entityPersister;
|
||||
|
||||
final PersistentClass bootEntityDescriptor = creationProcess.getCreationContext()
|
||||
.getBootModel()
|
||||
.getEntityBinding( entityPersister.getEntityName() );
|
||||
|
||||
propertyAccess = entityPersister.getRepresentationStrategy()
|
||||
.resolvePropertyAccess( bootEntityDescriptor.getIdentifierProperty() );
|
||||
|
||||
idRole = entityPersister.getNavigableRole().append( EntityIdentifierMapping.ROLE_LOCAL_NAME );
|
||||
sessionFactory = creationProcess.getCreationContext().getSessionFactory();
|
||||
}
|
||||
|
||||
@Override
|
||||
public PropertyAccess getPropertyAccess() {
|
||||
return propertyAccess;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getIdentifier(Object entity, SharedSessionContractImplementor session) {
|
||||
return propertyAccess.getGetter().get( entity );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setIdentifier(Object entity, Object id, SharedSessionContractImplementor session) {
|
||||
propertyAccess.getSetter().set( entity, id, session.getFactory() );
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object instantiate() {
|
||||
return entityPersister.getRepresentationStrategy()
|
||||
.getInstantiator()
|
||||
.instantiate( sessionFactory );
|
||||
}
|
||||
|
||||
@Override
|
||||
public MappingType getPartMappingType() {
|
||||
return getBasicType();
|
||||
}
|
||||
|
||||
@Override
|
||||
public MappingType getMappedTypeDescriptor() {
|
||||
return getBasicType();
|
||||
}
|
||||
|
||||
@Override
|
||||
public BasicType getBasicType() {
|
||||
return (BasicType) entityPersister.getIdentifierType();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getJdbcTypeCount(TypeConfiguration typeConfiguration) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitColumns(ColumnConsumer consumer) {
|
||||
consumer.accept( getMappedColumnExpression(), getContainingTableExpression(), getJdbcMapping() );
|
||||
}
|
||||
|
||||
@Override
|
||||
public EntityMappingType findContainingEntityMapping() {
|
||||
return entityPersister;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitJdbcTypes(
|
||||
Consumer<JdbcMapping> action,
|
||||
Clause clause,
|
||||
TypeConfiguration typeConfiguration) {
|
||||
action.accept( idType );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitJdbcValues(
|
||||
Object value,
|
||||
Clause clause,
|
||||
JdbcValuesConsumer valuesConsumer,
|
||||
SharedSessionContractImplementor session) {
|
||||
valuesConsumer.consume( value, idType );
|
||||
}
|
||||
|
||||
@Override
|
||||
public JavaTypeDescriptor getJavaTypeDescriptor() {
|
||||
return getMappedTypeDescriptor().getMappedJavaTypeDescriptor();
|
||||
}
|
||||
|
||||
@Override
|
||||
public NavigableRole getNavigableRole() {
|
||||
return idRole;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> DomainResult<T> createDomainResult(
|
||||
NavigablePath navigablePath,
|
||||
TableGroup tableGroup,
|
||||
String resultVariable,
|
||||
DomainResultCreationState creationState) {
|
||||
final SqlExpressionResolver expressionResolver = creationState.getSqlAstCreationState()
|
||||
.getSqlExpressionResolver();
|
||||
final TableReference rootTableReference;
|
||||
try {
|
||||
rootTableReference = tableGroup.resolveTableReference( rootTable );
|
||||
}
|
||||
catch (Exception e) {
|
||||
throw new IllegalStateException(
|
||||
String.format(
|
||||
Locale.ROOT,
|
||||
"Could not resolve table reference `%s` relative to TableGroup `%s` related with NavigablePath `%s`",
|
||||
rootTable,
|
||||
tableGroup,
|
||||
navigablePath
|
||||
),
|
||||
e
|
||||
);
|
||||
}
|
||||
|
||||
final Expression expression = expressionResolver.resolveSqlExpression(
|
||||
SqlExpressionResolver.createColumnReferenceKey( rootTableReference, pkColumnName ),
|
||||
sqlAstProcessingState -> new ColumnReference(
|
||||
rootTableReference.getIdentificationVariable(),
|
||||
pkColumnName,
|
||||
( (BasicValuedMapping) entityPersister.getIdentifierType() ).getJdbcMapping(),
|
||||
sessionFactory
|
||||
)
|
||||
);
|
||||
|
||||
final SqlSelection sqlSelection = expressionResolver.resolveSqlSelection(
|
||||
expression,
|
||||
idType.getExpressableJavaTypeDescriptor(),
|
||||
sessionFactory.getTypeConfiguration()
|
||||
);
|
||||
|
||||
//noinspection unchecked
|
||||
return new BasicResult(
|
||||
sqlSelection.getValuesArrayPosition(),
|
||||
resultVariable,
|
||||
entityPersister.getIdentifierMapping().getMappedTypeDescriptor().getMappedJavaTypeDescriptor(),
|
||||
navigablePath
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void applySqlSelections(
|
||||
NavigablePath navigablePath,
|
||||
TableGroup tableGroup,
|
||||
DomainResultCreationState creationState) {
|
||||
final SqlExpressionResolver expressionResolver = creationState.getSqlAstCreationState()
|
||||
.getSqlExpressionResolver();
|
||||
final TableReference rootTableReference = tableGroup.resolveTableReference( rootTable );
|
||||
|
||||
final Expression expression = expressionResolver.resolveSqlExpression(
|
||||
SqlExpressionResolver.createColumnReferenceKey( rootTableReference, pkColumnName ),
|
||||
sqlAstProcessingState -> new ColumnReference(
|
||||
rootTable,
|
||||
pkColumnName,
|
||||
( (BasicValuedModelPart) entityPersister.getIdentifierType() ).getJdbcMapping(),
|
||||
sessionFactory
|
||||
)
|
||||
);
|
||||
|
||||
// the act of resolving the expression -> selection applies it
|
||||
expressionResolver.resolveSqlSelection(
|
||||
expression,
|
||||
idType.getExpressableJavaTypeDescriptor(),
|
||||
sessionFactory.getTypeConfiguration()
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getContainingTableExpression() {
|
||||
return rootTable;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BasicValueConverter getConverter() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getMappedColumnExpression() {
|
||||
return pkColumnName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public JdbcMapping getJdbcMapping() {
|
||||
return idType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getFetchableName() {
|
||||
return entityPersister.getIdentifierPropertyName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public FetchStrategy getMappedFetchStrategy() {
|
||||
return FetchStrategy.IMMEDIATE_JOIN;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Fetch generateFetch(
|
||||
FetchParent fetchParent,
|
||||
NavigablePath fetchablePath,
|
||||
FetchTiming fetchTiming,
|
||||
boolean selected,
|
||||
LockMode lockMode,
|
||||
String resultVariable,
|
||||
DomainResultCreationState creationState) {
|
||||
return new BasicFetch<>(
|
||||
0,
|
||||
fetchParent,
|
||||
fetchablePath,
|
||||
this,
|
||||
false,
|
||||
null,
|
||||
FetchTiming.IMMEDIATE,
|
||||
creationState
|
||||
);
|
||||
}
|
||||
}
|
|
@ -7,8 +7,10 @@
|
|||
package org.hibernate.metamodel.mapping.internal;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import org.hibernate.HibernateException;
|
||||
import org.hibernate.LockMode;
|
||||
import org.hibernate.NotYetImplementedFor6Exception;
|
||||
import org.hibernate.engine.FetchStrategy;
|
||||
|
|
|
@ -9,13 +9,10 @@ package org.hibernate.metamodel.mapping.internal;
|
|||
import java.io.Serializable;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.SortedMap;
|
||||
import java.util.SortedSet;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import org.hibernate.FetchMode;
|
||||
import org.hibernate.LockMode;
|
||||
import org.hibernate.MappingException;
|
||||
import org.hibernate.NotYetImplementedFor6Exception;
|
||||
import org.hibernate.collection.internal.StandardArraySemantics;
|
||||
|
@ -31,7 +28,6 @@ import org.hibernate.engine.jdbc.env.spi.JdbcEnvironment;
|
|||
import org.hibernate.engine.jdbc.spi.JdbcServices;
|
||||
import org.hibernate.engine.spi.CascadeStyle;
|
||||
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||
import org.hibernate.engine.spi.SharedSessionContractImplementor;
|
||||
import org.hibernate.internal.util.collections.CollectionHelper;
|
||||
import org.hibernate.mapping.BasicValue;
|
||||
import org.hibernate.mapping.Collection;
|
||||
|
@ -47,28 +43,22 @@ import org.hibernate.mapping.ToOne;
|
|||
import org.hibernate.mapping.Value;
|
||||
import org.hibernate.metamodel.CollectionClassification;
|
||||
import org.hibernate.metamodel.MappingMetamodel;
|
||||
import org.hibernate.metamodel.mapping.BasicEntityIdentifierMapping;
|
||||
import org.hibernate.metamodel.mapping.BasicValuedMapping;
|
||||
import org.hibernate.metamodel.mapping.BasicValuedModelPart;
|
||||
import org.hibernate.metamodel.mapping.CollectionIdentifierDescriptor;
|
||||
import org.hibernate.metamodel.mapping.CollectionMappingType;
|
||||
import org.hibernate.metamodel.mapping.CollectionPart;
|
||||
import org.hibernate.metamodel.mapping.ColumnConsumer;
|
||||
import org.hibernate.metamodel.mapping.CompositeIdentifierMapping;
|
||||
import org.hibernate.metamodel.mapping.EmbeddableMappingType;
|
||||
import org.hibernate.metamodel.mapping.EntityIdentifierMapping;
|
||||
import org.hibernate.metamodel.mapping.EntityMappingType;
|
||||
import org.hibernate.metamodel.mapping.ForeignKeyDescriptor;
|
||||
import org.hibernate.metamodel.mapping.JdbcMapping;
|
||||
import org.hibernate.metamodel.mapping.ManagedMappingType;
|
||||
import org.hibernate.metamodel.mapping.MappingType;
|
||||
import org.hibernate.metamodel.mapping.ModelPart;
|
||||
import org.hibernate.metamodel.mapping.PluralAttributeMapping;
|
||||
import org.hibernate.metamodel.mapping.SingularAttributeMapping;
|
||||
import org.hibernate.metamodel.mapping.StateArrayContributorMetadata;
|
||||
import org.hibernate.metamodel.mapping.StateArrayContributorMetadataAccess;
|
||||
import org.hibernate.metamodel.model.convert.spi.BasicValueConverter;
|
||||
import org.hibernate.metamodel.model.domain.NavigableRole;
|
||||
import org.hibernate.metamodel.spi.RuntimeModelCreationContext;
|
||||
import org.hibernate.persister.collection.CollectionPersister;
|
||||
import org.hibernate.persister.collection.SQLLoadableCollection;
|
||||
|
@ -76,21 +66,7 @@ import org.hibernate.persister.entity.EntityPersister;
|
|||
import org.hibernate.persister.entity.Joinable;
|
||||
import org.hibernate.persister.walking.internal.FetchStrategyHelper;
|
||||
import org.hibernate.property.access.spi.PropertyAccess;
|
||||
import org.hibernate.query.NavigablePath;
|
||||
import org.hibernate.sql.ast.Clause;
|
||||
import org.hibernate.sql.ast.spi.SqlAliasStemHelper;
|
||||
import org.hibernate.sql.ast.spi.SqlExpressionResolver;
|
||||
import org.hibernate.sql.ast.spi.SqlSelection;
|
||||
import org.hibernate.sql.ast.tree.expression.ColumnReference;
|
||||
import org.hibernate.sql.ast.tree.expression.Expression;
|
||||
import org.hibernate.sql.ast.tree.from.TableGroup;
|
||||
import org.hibernate.sql.ast.tree.from.TableReference;
|
||||
import org.hibernate.sql.results.graph.DomainResult;
|
||||
import org.hibernate.sql.results.graph.DomainResultCreationState;
|
||||
import org.hibernate.sql.results.graph.Fetch;
|
||||
import org.hibernate.sql.results.graph.FetchParent;
|
||||
import org.hibernate.sql.results.graph.basic.BasicFetch;
|
||||
import org.hibernate.sql.results.graph.basic.BasicResult;
|
||||
import org.hibernate.type.AssociationType;
|
||||
import org.hibernate.type.BasicType;
|
||||
import org.hibernate.type.CompositeType;
|
||||
|
@ -101,7 +77,6 @@ import org.hibernate.type.descriptor.java.ImmutableMutabilityPlan;
|
|||
import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
|
||||
import org.hibernate.type.descriptor.java.MutabilityPlan;
|
||||
import org.hibernate.type.descriptor.java.spi.JavaTypeDescriptorRegistry;
|
||||
import org.hibernate.type.spi.TypeConfiguration;
|
||||
|
||||
/**
|
||||
* @author Steve Ebersole
|
||||
|
@ -113,236 +88,7 @@ public class MappingModelCreationHelper {
|
|||
private MappingModelCreationHelper() {
|
||||
}
|
||||
|
||||
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
// EntityIdentifier
|
||||
|
||||
public static BasicEntityIdentifierMapping buildSimpleIdentifierMapping(
|
||||
EntityPersister entityPersister,
|
||||
String rootTable,
|
||||
String pkColumnName,
|
||||
BasicType idType,
|
||||
MappingModelCreationProcess creationProcess) {
|
||||
assert entityPersister.hasIdentifierProperty();
|
||||
assert entityPersister.getIdentifierPropertyName() != null;
|
||||
|
||||
final PersistentClass bootEntityDescriptor = creationProcess.getCreationContext()
|
||||
.getBootModel()
|
||||
.getEntityBinding( entityPersister.getEntityName() );
|
||||
|
||||
final PropertyAccess propertyAccess = entityPersister.getRepresentationStrategy()
|
||||
.resolvePropertyAccess( bootEntityDescriptor.getIdentifierProperty() );
|
||||
|
||||
final NavigableRole idRole = entityPersister.getNavigableRole().append( EntityIdentifierMapping.ROLE_LOCAL_NAME );
|
||||
|
||||
return new BasicEntityIdentifierMapping() {
|
||||
@Override
|
||||
public PropertyAccess getPropertyAccess() {
|
||||
return propertyAccess;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getIdentifier(Object entity, SharedSessionContractImplementor session) {
|
||||
return propertyAccess.getGetter().get( entity );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setIdentifier(Object entity, Object id, SharedSessionContractImplementor session) {
|
||||
propertyAccess.getSetter().set( entity, id, session.getFactory() );
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object instantiate() {
|
||||
return entityPersister.getRepresentationStrategy()
|
||||
.getInstantiator()
|
||||
.instantiate( creationProcess.getCreationContext().getSessionFactory() );
|
||||
}
|
||||
|
||||
@Override
|
||||
public MappingType getPartMappingType() {
|
||||
return getBasicType();
|
||||
}
|
||||
|
||||
@Override
|
||||
public MappingType getMappedTypeDescriptor() {
|
||||
return getBasicType();
|
||||
}
|
||||
|
||||
@Override
|
||||
public BasicType getBasicType() {
|
||||
return (BasicType) entityPersister.getIdentifierType();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getJdbcTypeCount(TypeConfiguration typeConfiguration) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitColumns(ColumnConsumer consumer) {
|
||||
consumer.accept( getMappedColumnExpression(), getContainingTableExpression(), getJdbcMapping() );
|
||||
}
|
||||
|
||||
@Override
|
||||
public EntityMappingType findContainingEntityMapping() {
|
||||
return entityPersister;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitJdbcTypes(
|
||||
Consumer<JdbcMapping> action,
|
||||
Clause clause,
|
||||
TypeConfiguration typeConfiguration) {
|
||||
action.accept( idType );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitJdbcValues(
|
||||
Object value,
|
||||
Clause clause,
|
||||
JdbcValuesConsumer valuesConsumer,
|
||||
SharedSessionContractImplementor session) {
|
||||
valuesConsumer.consume( value, idType );
|
||||
}
|
||||
|
||||
@Override
|
||||
public JavaTypeDescriptor getJavaTypeDescriptor() {
|
||||
return getMappedTypeDescriptor().getMappedJavaTypeDescriptor();
|
||||
}
|
||||
|
||||
@Override
|
||||
public NavigableRole getNavigableRole() {
|
||||
return idRole;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> DomainResult<T> createDomainResult(
|
||||
NavigablePath navigablePath,
|
||||
TableGroup tableGroup,
|
||||
String resultVariable,
|
||||
DomainResultCreationState creationState) {
|
||||
final SqlExpressionResolver expressionResolver = creationState.getSqlAstCreationState().getSqlExpressionResolver();
|
||||
final TableReference rootTableReference;
|
||||
try {
|
||||
rootTableReference = tableGroup.resolveTableReference( rootTable );
|
||||
}
|
||||
catch (Exception e) {
|
||||
throw new IllegalStateException(
|
||||
String.format(
|
||||
Locale.ROOT,
|
||||
"Could not resolve table reference `%s` relative to TableGroup `%s` related with NavigablePath `%s`",
|
||||
rootTable,
|
||||
tableGroup,
|
||||
navigablePath
|
||||
),
|
||||
e
|
||||
);
|
||||
}
|
||||
|
||||
final Expression expression = expressionResolver.resolveSqlExpression(
|
||||
SqlExpressionResolver.createColumnReferenceKey( rootTableReference, pkColumnName ),
|
||||
sqlAstProcessingState -> new ColumnReference(
|
||||
rootTableReference.getIdentificationVariable(),
|
||||
pkColumnName,
|
||||
( (BasicValuedMapping) entityPersister.getIdentifierType() ).getJdbcMapping(),
|
||||
creationProcess.getCreationContext().getSessionFactory()
|
||||
)
|
||||
);
|
||||
|
||||
final SqlSelection sqlSelection = expressionResolver.resolveSqlSelection(
|
||||
expression,
|
||||
idType.getExpressableJavaTypeDescriptor(),
|
||||
creationProcess.getCreationContext().getSessionFactory().getTypeConfiguration()
|
||||
);
|
||||
|
||||
//noinspection unchecked
|
||||
return new BasicResult(
|
||||
sqlSelection.getValuesArrayPosition(),
|
||||
resultVariable,
|
||||
entityPersister.getIdentifierMapping().getMappedTypeDescriptor().getMappedJavaTypeDescriptor(),
|
||||
navigablePath
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void applySqlSelections(
|
||||
NavigablePath navigablePath,
|
||||
TableGroup tableGroup,
|
||||
DomainResultCreationState creationState) {
|
||||
final SqlExpressionResolver expressionResolver = creationState.getSqlAstCreationState().getSqlExpressionResolver();
|
||||
final TableReference rootTableReference = tableGroup.resolveTableReference( rootTable );
|
||||
|
||||
final Expression expression = expressionResolver.resolveSqlExpression(
|
||||
SqlExpressionResolver.createColumnReferenceKey( rootTableReference, pkColumnName ),
|
||||
sqlAstProcessingState -> new ColumnReference(
|
||||
rootTable,
|
||||
pkColumnName,
|
||||
( (BasicValuedModelPart) entityPersister.getIdentifierType() ).getJdbcMapping(),
|
||||
creationProcess.getCreationContext().getSessionFactory()
|
||||
)
|
||||
);
|
||||
|
||||
// the act of resolving the expression -> selection applies it
|
||||
expressionResolver.resolveSqlSelection(
|
||||
expression,
|
||||
idType.getExpressableJavaTypeDescriptor(),
|
||||
creationProcess.getCreationContext().getSessionFactory().getTypeConfiguration()
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getContainingTableExpression() {
|
||||
return rootTable;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BasicValueConverter getConverter() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getMappedColumnExpression() {
|
||||
return pkColumnName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public JdbcMapping getJdbcMapping() {
|
||||
return idType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getFetchableName() {
|
||||
return entityPersister.getIdentifierPropertyName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public FetchStrategy getMappedFetchStrategy() {
|
||||
return FetchStrategy.IMMEDIATE_JOIN;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Fetch generateFetch(
|
||||
FetchParent fetchParent,
|
||||
NavigablePath fetchablePath,
|
||||
FetchTiming fetchTiming,
|
||||
boolean selected,
|
||||
LockMode lockMode,
|
||||
String resultVariable,
|
||||
DomainResultCreationState creationState) {
|
||||
return new BasicFetch<>(
|
||||
0,
|
||||
fetchParent,
|
||||
fetchablePath,
|
||||
this,
|
||||
false,
|
||||
null,
|
||||
FetchTiming.IMMEDIATE,
|
||||
creationState
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
public static EntityIdentifierMapping buildEncapsulatedCompositeIdentifierMapping(
|
||||
EntityPersister entityPersister,
|
||||
|
|
|
@ -141,6 +141,7 @@ import org.hibernate.metamodel.mapping.Queryable;
|
|||
import org.hibernate.metamodel.mapping.SingularAttributeMapping;
|
||||
import org.hibernate.metamodel.mapping.StateArrayContributorMapping;
|
||||
import org.hibernate.metamodel.mapping.StateArrayContributorMetadata;
|
||||
import org.hibernate.metamodel.mapping.internal.BasicEntityIdentifierMappingImpl;
|
||||
import org.hibernate.metamodel.mapping.internal.EntityDiscriminatorMappingImpl;
|
||||
import org.hibernate.metamodel.mapping.internal.InFlightEntityMappingType;
|
||||
import org.hibernate.metamodel.mapping.internal.MappingModelCreationHelper;
|
||||
|
@ -5984,7 +5985,7 @@ public abstract class AbstractEntityPersister
|
|||
return generateNonEncapsulatedCompositeIdentifierMapping( creationProcess, bootEntityDescriptor, cidType );
|
||||
}
|
||||
|
||||
return MappingModelCreationHelper.buildSimpleIdentifierMapping(
|
||||
return new BasicEntityIdentifierMappingImpl(
|
||||
this,
|
||||
getRootTableName(),
|
||||
rootTableKeyColumnNames[0],
|
||||
|
|
|
@ -26,7 +26,7 @@ public abstract class AbstractColumnReferenceQualifier implements ColumnReferenc
|
|||
|
||||
@Override
|
||||
public TableReference resolveTableReference(String tableExpression, Supplier<TableReference> creator) {
|
||||
final TableReference existing = resolveTableReference( tableExpression );
|
||||
final TableReference existing = resolveTableReferenceInternal( tableExpression );
|
||||
if ( existing != null ) {
|
||||
return existing;
|
||||
}
|
||||
|
|
|
@ -114,12 +114,12 @@ public class StandardTableGroup extends AbstractTableGroup {
|
|||
return potentiallyCreateTableReference( tableExpression );
|
||||
}
|
||||
|
||||
// for ( TableGroupJoin tableGroupJoin : getTableGroupJoins() ) {
|
||||
// final TableReference primaryTableReference = tableGroupJoin.getJoinedGroup().getPrimaryTableReference();
|
||||
// if ( primaryTableReference.getTableExpression().equals( tableExpression ) ) {
|
||||
// return primaryTableReference;
|
||||
// }
|
||||
// }
|
||||
for ( TableGroupJoin tableGroupJoin : getTableGroupJoins() ) {
|
||||
final TableReference primaryTableReference = tableGroupJoin.getJoinedGroup().getPrimaryTableReference();
|
||||
if ( primaryTableReference.getTableExpression().equals( tableExpression ) ) {
|
||||
return primaryTableReference;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue