Refactoring
This commit is contained in:
parent
3222b52ab2
commit
16d81eb4bf
|
@ -383,87 +383,7 @@ public class LoaderSelectBuilder {
|
||||||
|
|
||||||
final List<Fetch> fetches = new ArrayList<>();
|
final List<Fetch> fetches = new ArrayList<>();
|
||||||
|
|
||||||
final Consumer<Fetchable> processor = fetchable -> {
|
final Consumer<Fetchable> processor = createFetchableConsumer( fetchParent, querySpec, creationState, fetches );
|
||||||
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 FetchableContainer referencedMappingContainer = fetchParent.getReferencedMappingContainer();
|
final FetchableContainer referencedMappingContainer = fetchParent.getReferencedMappingContainer();
|
||||||
referencedMappingContainer.visitKeyFetchables( processor, null );
|
referencedMappingContainer.visitKeyFetchables( processor, null );
|
||||||
|
@ -472,6 +392,93 @@ public class LoaderSelectBuilder {
|
||||||
return fetches;
|
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(
|
private void applyOrdering(
|
||||||
QuerySpec ast,
|
QuerySpec ast,
|
||||||
NavigablePath navigablePath,
|
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;
|
package org.hibernate.metamodel.mapping.internal;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.hibernate.HibernateException;
|
||||||
import org.hibernate.LockMode;
|
import org.hibernate.LockMode;
|
||||||
import org.hibernate.NotYetImplementedFor6Exception;
|
import org.hibernate.NotYetImplementedFor6Exception;
|
||||||
import org.hibernate.engine.FetchStrategy;
|
import org.hibernate.engine.FetchStrategy;
|
||||||
|
|
|
@ -9,13 +9,10 @@ package org.hibernate.metamodel.mapping.internal;
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Locale;
|
|
||||||
import java.util.SortedMap;
|
import java.util.SortedMap;
|
||||||
import java.util.SortedSet;
|
import java.util.SortedSet;
|
||||||
import java.util.function.Consumer;
|
|
||||||
|
|
||||||
import org.hibernate.FetchMode;
|
import org.hibernate.FetchMode;
|
||||||
import org.hibernate.LockMode;
|
|
||||||
import org.hibernate.MappingException;
|
import org.hibernate.MappingException;
|
||||||
import org.hibernate.NotYetImplementedFor6Exception;
|
import org.hibernate.NotYetImplementedFor6Exception;
|
||||||
import org.hibernate.collection.internal.StandardArraySemantics;
|
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.jdbc.spi.JdbcServices;
|
||||||
import org.hibernate.engine.spi.CascadeStyle;
|
import org.hibernate.engine.spi.CascadeStyle;
|
||||||
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||||
import org.hibernate.engine.spi.SharedSessionContractImplementor;
|
|
||||||
import org.hibernate.internal.util.collections.CollectionHelper;
|
import org.hibernate.internal.util.collections.CollectionHelper;
|
||||||
import org.hibernate.mapping.BasicValue;
|
import org.hibernate.mapping.BasicValue;
|
||||||
import org.hibernate.mapping.Collection;
|
import org.hibernate.mapping.Collection;
|
||||||
|
@ -47,28 +43,22 @@ import org.hibernate.mapping.ToOne;
|
||||||
import org.hibernate.mapping.Value;
|
import org.hibernate.mapping.Value;
|
||||||
import org.hibernate.metamodel.CollectionClassification;
|
import org.hibernate.metamodel.CollectionClassification;
|
||||||
import org.hibernate.metamodel.MappingMetamodel;
|
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.BasicValuedModelPart;
|
||||||
import org.hibernate.metamodel.mapping.CollectionIdentifierDescriptor;
|
import org.hibernate.metamodel.mapping.CollectionIdentifierDescriptor;
|
||||||
import org.hibernate.metamodel.mapping.CollectionMappingType;
|
import org.hibernate.metamodel.mapping.CollectionMappingType;
|
||||||
import org.hibernate.metamodel.mapping.CollectionPart;
|
import org.hibernate.metamodel.mapping.CollectionPart;
|
||||||
import org.hibernate.metamodel.mapping.ColumnConsumer;
|
|
||||||
import org.hibernate.metamodel.mapping.CompositeIdentifierMapping;
|
import org.hibernate.metamodel.mapping.CompositeIdentifierMapping;
|
||||||
import org.hibernate.metamodel.mapping.EmbeddableMappingType;
|
import org.hibernate.metamodel.mapping.EmbeddableMappingType;
|
||||||
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.ForeignKeyDescriptor;
|
import org.hibernate.metamodel.mapping.ForeignKeyDescriptor;
|
||||||
import org.hibernate.metamodel.mapping.JdbcMapping;
|
|
||||||
import org.hibernate.metamodel.mapping.ManagedMappingType;
|
import org.hibernate.metamodel.mapping.ManagedMappingType;
|
||||||
import org.hibernate.metamodel.mapping.MappingType;
|
|
||||||
import org.hibernate.metamodel.mapping.ModelPart;
|
import org.hibernate.metamodel.mapping.ModelPart;
|
||||||
import org.hibernate.metamodel.mapping.PluralAttributeMapping;
|
import org.hibernate.metamodel.mapping.PluralAttributeMapping;
|
||||||
import org.hibernate.metamodel.mapping.SingularAttributeMapping;
|
import org.hibernate.metamodel.mapping.SingularAttributeMapping;
|
||||||
import org.hibernate.metamodel.mapping.StateArrayContributorMetadata;
|
import org.hibernate.metamodel.mapping.StateArrayContributorMetadata;
|
||||||
import org.hibernate.metamodel.mapping.StateArrayContributorMetadataAccess;
|
import org.hibernate.metamodel.mapping.StateArrayContributorMetadataAccess;
|
||||||
import org.hibernate.metamodel.model.convert.spi.BasicValueConverter;
|
import org.hibernate.metamodel.model.convert.spi.BasicValueConverter;
|
||||||
import org.hibernate.metamodel.model.domain.NavigableRole;
|
|
||||||
import org.hibernate.metamodel.spi.RuntimeModelCreationContext;
|
import org.hibernate.metamodel.spi.RuntimeModelCreationContext;
|
||||||
import org.hibernate.persister.collection.CollectionPersister;
|
import org.hibernate.persister.collection.CollectionPersister;
|
||||||
import org.hibernate.persister.collection.SQLLoadableCollection;
|
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.entity.Joinable;
|
||||||
import org.hibernate.persister.walking.internal.FetchStrategyHelper;
|
import org.hibernate.persister.walking.internal.FetchStrategyHelper;
|
||||||
import org.hibernate.property.access.spi.PropertyAccess;
|
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.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.AssociationType;
|
||||||
import org.hibernate.type.BasicType;
|
import org.hibernate.type.BasicType;
|
||||||
import org.hibernate.type.CompositeType;
|
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.JavaTypeDescriptor;
|
||||||
import org.hibernate.type.descriptor.java.MutabilityPlan;
|
import org.hibernate.type.descriptor.java.MutabilityPlan;
|
||||||
import org.hibernate.type.descriptor.java.spi.JavaTypeDescriptorRegistry;
|
import org.hibernate.type.descriptor.java.spi.JavaTypeDescriptorRegistry;
|
||||||
import org.hibernate.type.spi.TypeConfiguration;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Steve Ebersole
|
* @author Steve Ebersole
|
||||||
|
@ -113,236 +88,7 @@ public class MappingModelCreationHelper {
|
||||||
private 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(
|
public static EntityIdentifierMapping buildEncapsulatedCompositeIdentifierMapping(
|
||||||
EntityPersister entityPersister,
|
EntityPersister entityPersister,
|
||||||
|
|
|
@ -141,6 +141,7 @@ import org.hibernate.metamodel.mapping.Queryable;
|
||||||
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;
|
||||||
|
import org.hibernate.metamodel.mapping.internal.BasicEntityIdentifierMappingImpl;
|
||||||
import org.hibernate.metamodel.mapping.internal.EntityDiscriminatorMappingImpl;
|
import org.hibernate.metamodel.mapping.internal.EntityDiscriminatorMappingImpl;
|
||||||
import org.hibernate.metamodel.mapping.internal.InFlightEntityMappingType;
|
import org.hibernate.metamodel.mapping.internal.InFlightEntityMappingType;
|
||||||
import org.hibernate.metamodel.mapping.internal.MappingModelCreationHelper;
|
import org.hibernate.metamodel.mapping.internal.MappingModelCreationHelper;
|
||||||
|
@ -5984,7 +5985,7 @@ public abstract class AbstractEntityPersister
|
||||||
return generateNonEncapsulatedCompositeIdentifierMapping( creationProcess, bootEntityDescriptor, cidType );
|
return generateNonEncapsulatedCompositeIdentifierMapping( creationProcess, bootEntityDescriptor, cidType );
|
||||||
}
|
}
|
||||||
|
|
||||||
return MappingModelCreationHelper.buildSimpleIdentifierMapping(
|
return new BasicEntityIdentifierMappingImpl(
|
||||||
this,
|
this,
|
||||||
getRootTableName(),
|
getRootTableName(),
|
||||||
rootTableKeyColumnNames[0],
|
rootTableKeyColumnNames[0],
|
||||||
|
|
|
@ -26,7 +26,7 @@ public abstract class AbstractColumnReferenceQualifier implements ColumnReferenc
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public TableReference resolveTableReference(String tableExpression, Supplier<TableReference> creator) {
|
public TableReference resolveTableReference(String tableExpression, Supplier<TableReference> creator) {
|
||||||
final TableReference existing = resolveTableReference( tableExpression );
|
final TableReference existing = resolveTableReferenceInternal( tableExpression );
|
||||||
if ( existing != null ) {
|
if ( existing != null ) {
|
||||||
return existing;
|
return existing;
|
||||||
}
|
}
|
||||||
|
|
|
@ -114,12 +114,12 @@ public class StandardTableGroup extends AbstractTableGroup {
|
||||||
return potentiallyCreateTableReference( tableExpression );
|
return potentiallyCreateTableReference( tableExpression );
|
||||||
}
|
}
|
||||||
|
|
||||||
// for ( TableGroupJoin tableGroupJoin : getTableGroupJoins() ) {
|
for ( TableGroupJoin tableGroupJoin : getTableGroupJoins() ) {
|
||||||
// final TableReference primaryTableReference = tableGroupJoin.getJoinedGroup().getPrimaryTableReference();
|
final TableReference primaryTableReference = tableGroupJoin.getJoinedGroup().getPrimaryTableReference();
|
||||||
// if ( primaryTableReference.getTableExpression().equals( tableExpression ) ) {
|
if ( primaryTableReference.getTableExpression().equals( tableExpression ) ) {
|
||||||
// return primaryTableReference;
|
return primaryTableReference;
|
||||||
// }
|
}
|
||||||
// }
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue