Implement support for avoiding joins when accessing FK keys

This commit is contained in:
Christian Beikov 2021-04-13 09:30:44 +02:00
parent c74e5ef595
commit df9d285f2c
110 changed files with 952 additions and 539 deletions

View File

@ -7,6 +7,7 @@
package org.hibernate.userguide.mapping.identifier.composite;
import java.sql.Timestamp;
import java.time.OffsetDateTime;
import org.hibernate.dialect.H2Dialect;
import org.hibernate.jpa.test.BaseEntityManagerFunctionalTestCase;
@ -33,15 +34,16 @@ public class EmbeddedIdDatabaseGeneratedValueTest extends BaseEntityManagerFunct
@TestForIssue(jiraKey = "HHH-13096")
public void test() {
final EventId eventId = doInJPA( this::entityManagerFactory, entityManager -> {
// On H2 1.4.199+ CURRENT_TIMESTAMP returns a timestamp with timezone
//tag::identifiers-composite-generated-database-example[]
Timestamp currentTimestamp = (Timestamp) entityManager
OffsetDateTime currentTimestamp = (OffsetDateTime) entityManager
.createNativeQuery(
"SELECT CURRENT_TIMESTAMP" )
.getSingleResult();
EventId id = new EventId();
id.setCategory( 1 );
id.setCreatedOn( currentTimestamp );
id.setCreatedOn( Timestamp.from( currentTimestamp.toInstant() ) );
Event event = new Event();
event.setId( id );

View File

@ -101,7 +101,7 @@ public abstract class AbstractNaturalIdLoader<T> implements NaturalIdLoader<T> {
final List<Fetch> fetches = new ArrayList<>( naturalIdMapping.getNaturalIdAttributes().size() );
fetchParent.getReferencedMappingContainer().visitFetchables(
fetchable -> {
final NavigablePath navigablePath = fetchParent.getNavigablePath().append( fetchable.getFetchableName() );
final NavigablePath navigablePath = fetchParent.resolveNavigablePath( fetchable );
final Fetch fetch = fetchParent.generateFetchableFetch(
fetchable,
navigablePath,
@ -280,7 +280,7 @@ public abstract class AbstractNaturalIdLoader<T> implements NaturalIdLoader<T> {
SelectableMapping selectableMapping,
SqlExpressionResolver sqlExpressionResolver,
SessionFactoryImplementor sessionFactory) {
final TableReference tableReference = rootTableGroup.getTableReference( selectableMapping.getContainingTableExpression() );
final TableReference tableReference = rootTableGroup.getTableReference( rootTableGroup.getNavigablePath(), selectableMapping.getContainingTableExpression() );
if ( tableReference == null ) {
throw new IllegalStateException(
String.format(
@ -321,7 +321,7 @@ public abstract class AbstractNaturalIdLoader<T> implements NaturalIdLoader<T> {
fetchParent.getReferencedMappingContainer().visitFetchables(
(fetchable) -> {
final NavigablePath navigablePath = fetchParent.getNavigablePath().append( fetchable.getFetchableName() );
final NavigablePath navigablePath = fetchParent.resolveNavigablePath( fetchable );
final Fetch fetch = fetchParent.generateFetchableFetch(
fetchable,
navigablePath,

View File

@ -109,10 +109,13 @@ class DatabaseSnapshotExecutor {
domainResults.add(
new QueryLiteral<>( null, IntegerType.INSTANCE ).createDomainResult( null, state )
);
final NavigablePath idNavigablePath = rootPath.append( entityDescriptor.getIdentifierMapping().getNavigableRole().getNavigableName() );
entityDescriptor.getIdentifierMapping().forEachSelectable(
(columnIndex, selection) -> {
final TableReference tableReference = rootTableGroup.resolveTableReference( selection.getContainingTableExpression() );
final TableReference tableReference = rootTableGroup.resolveTableReference(
idNavigablePath,
selection.getContainingTableExpression()
);
final JdbcParameter jdbcParameter = new JdbcParameterImpl( selection.getJdbcMapping() );
jdbcParameters.add( jdbcParameter );

View File

@ -467,12 +467,13 @@ public class LoaderSelectBuilder {
Consumer<JdbcParameter> jdbcParameterConsumer,
LoaderSqlAstCreationState sqlAstCreationState) {
final SqlExpressionResolver sqlExpressionResolver = sqlAstCreationState.getSqlExpressionResolver();
final NavigablePath navigablePath = rootNavigablePath.append( modelPart.getNavigableRole().getNavigableName() );
if ( numberColumns == 1 ) {
modelPart.forEachSelectable(
(columnIndex, selection) -> {
final TableReference tableReference = rootTableGroup.resolveTableReference(
selection.getContainingTableExpression() );
navigablePath, selection.getContainingTableExpression() );
final ColumnReference columnRef =
(ColumnReference) sqlExpressionResolver.resolveSqlExpression(
createColumnReferenceKey( tableReference, selection.getSelectionExpression() ),
@ -511,7 +512,7 @@ public class LoaderSelectBuilder {
modelPart.forEachSelectable(
(columnIndex, selection) -> {
final TableReference tableReference = rootTableGroup.resolveTableReference( selection.getContainingTableExpression() );
final TableReference tableReference = rootTableGroup.resolveTableReference( navigablePath, selection.getContainingTableExpression() );
columnReferences.add(
(ColumnReference) sqlExpressionResolver.resolveSqlExpression(
createColumnReferenceKey( tableReference, selection.getSelectionExpression() ),
@ -629,7 +630,6 @@ public class LoaderSelectBuilder {
List<Fetch> fetches,
List<String> bagRoles) {
return (fetchable, isKeyFetchable) -> {
final NavigablePath parentNavigablePath = fetchParent.getNavigablePath();
final NavigablePath fetchablePath;
if ( isKeyFetchable ) {
@ -659,16 +659,16 @@ public class LoaderSelectBuilder {
if ( identifierMapping != null ) {
fetchablePath = new EntityIdentifierNavigablePath(
parentNavigablePath,
fetchParent.getNavigablePath(),
attributeName( identifierMapping )
);
}
else {
fetchablePath = parentNavigablePath.append( fetchable.getFetchableName() );
fetchablePath = fetchParent.resolveNavigablePath( fetchable );
}
}
else {
fetchablePath = parentNavigablePath.append( fetchable.getFetchableName() );
fetchablePath = fetchParent.resolveNavigablePath( fetchable );
}
final Fetch biDirectionalFetch = fetchable.resolveCircularFetch(
@ -879,6 +879,7 @@ public class LoaderSelectBuilder {
final PluralAttributeMapping attributeMapping = (PluralAttributeMapping) loadable;
final ForeignKeyDescriptor fkDescriptor = attributeMapping.getKeyDescriptor();
final NavigablePath navigablePath = rootNavigablePath.append( attributeMapping.getAttributeName() );
final Expression fkExpression;
@ -892,7 +893,7 @@ public class LoaderSelectBuilder {
simpleFkDescriptor.getSelectionExpression()
),
sqlAstProcessingState -> new ColumnReference(
rootTableGroup.resolveTableReference( simpleFkDescriptor.getContainingTableExpression() ),
rootTableGroup.resolveTableReference( navigablePath, simpleFkDescriptor.getContainingTableExpression() ),
simpleFkDescriptor.getSelectionExpression(),
false,
null,
@ -914,7 +915,7 @@ public class LoaderSelectBuilder {
selection.getSelectionExpression()
),
sqlAstProcessingState -> new ColumnReference(
rootTableGroup.resolveTableReference( selection.getContainingTableExpression() ),
rootTableGroup.resolveTableReference( navigablePath, selection.getContainingTableExpression() ),
selection,
this.creationContext.getSessionFactory()
)
@ -961,11 +962,12 @@ public class LoaderSelectBuilder {
loadingSqlAst.getFromClause().visitRoots( subQuery.getFromClause()::addRoot );
final SqlExpressionResolver sqlExpressionResolver = creationState.getSqlExpressionResolver();
final NavigablePath navigablePath = ownerTableGroup.getNavigablePath().append( attributeMapping.getAttributeName() );
fkDescriptor.visitTargetSelectables(
(valuesPosition, selection) -> {
// for each column, resolve a SqlSelection and add it to the sub-query select-clause
final TableReference tableReference = ownerTableGroup.resolveTableReference( selection.getContainingTableExpression() );
final TableReference tableReference = ownerTableGroup.resolveTableReference( navigablePath, selection.getContainingTableExpression() );
final Expression expression = sqlExpressionResolver.resolveSqlExpression(
createColumnReferenceKey( tableReference, selection.getSelectionExpression() ),
sqlAstProcessingState -> new ColumnReference(

View File

@ -162,6 +162,7 @@ public abstract class AbstractCompositeIdentifierMapping
TableGroup lhs,
String explicitSourceAlias,
SqlAstJoinType sqlAstJoinType,
boolean fetched,
LockMode lockMode,
SqlAliasBaseGenerator aliasBaseGenerator,
SqlExpressionResolver sqlExpressionResolver,
@ -228,12 +229,13 @@ public abstract class AbstractCompositeIdentifierMapping
SqlAstCreationState sqlAstCreationState) {
final SelectableMappings selectableMappings = getEmbeddableTypeDescriptor();
final List<ColumnReference> columnReferences = CollectionHelper.arrayList( selectableMappings.getJdbcTypeCount() );
final TableReference defaultTableReference = tableGroup.resolveTableReference( getContainingTableExpression() );
final NavigablePath navigablePath = tableGroup.getNavigablePath().append( getNavigableRole().getNavigableName() );
final TableReference defaultTableReference = tableGroup.resolveTableReference( navigablePath, getContainingTableExpression() );
getEmbeddableTypeDescriptor().forEachSelectable(
(columnIndex, selection) -> {
final TableReference tableReference = selection.getContainingTableExpression().equals( defaultTableReference.getTableExpression() )
? defaultTableReference
: tableGroup.resolveTableReference( selection.getContainingTableExpression() );
: tableGroup.resolveTableReference( navigablePath, selection.getContainingTableExpression() );
final Expression columnReference = sqlAstCreationState.getSqlExpressionResolver()
.resolveSqlExpression(
SqlExpressionResolver.createColumnReferenceKey(

View File

@ -454,6 +454,7 @@ public class EmbeddableMappingType implements ManagedMappingType, SelectableMapp
attributeIndex,
bootPropertyDescriptor,
entityPersister,
entityPersister,
(EntityType) subtype,
getRepresentationStrategy().resolvePropertyAccess( bootPropertyDescriptor ),
compositeType.getCascadeStyle( attributeIndex ),

View File

@ -32,6 +32,8 @@ public interface ForeignKeyDescriptor extends VirtualModelPart {
ModelPart getKeyPart();
ModelPart getTargetPart();
/**
* Create a DomainResult for the referring-side of the fk
*/

View File

@ -57,7 +57,7 @@ public abstract class AbstractDomainPath implements DomainPath {
SqlAstCreationState creationState) {
if ( referenceModelPart instanceof BasicValuedModelPart ) {
final BasicValuedModelPart selection = (BasicValuedModelPart) referenceModelPart;
final TableReference tableReference = tableGroup.resolveTableReference( selection.getContainingTableExpression() );
final TableReference tableReference = tableGroup.resolveTableReference( getNavigablePath(), selection.getContainingTableExpression() );
return creationState.getSqlExpressionResolver().resolveSqlExpression(
SqlExpressionResolver.createColumnReferenceKey(
selection.getContainingTableExpression(),
@ -221,7 +221,7 @@ public abstract class AbstractDomainPath implements DomainPath {
String collation,
SortOrder sortOrder,
SqlAstCreationState creationState) {
final TableReference tableReference = tableGroup.resolveTableReference( selection.getContainingTableExpression() );
final TableReference tableReference = tableGroup.resolveTableReference( getNavigablePath(), selection.getContainingTableExpression() );
final Expression expression = creationState.getSqlExpressionResolver().resolveSqlExpression(
SqlExpressionResolver.createColumnReferenceKey(
selection.getContainingTableExpression(),

View File

@ -190,7 +190,7 @@ public class AnyDiscriminatorPart implements BasicValuedModelPart, FetchOptions,
final SqlExpressionResolver sqlExpressionResolver = sqlAstCreationState.getSqlExpressionResolver();
final TableGroup tableGroup = fromClauseAccess.getTableGroup( fetchablePath.getParent().getParent() );
final TableReference tableReference = tableGroup.getTableReference( table );
final TableReference tableReference = tableGroup.getTableReference( fetchablePath, table );
final Expression columnReference = sqlExpressionResolver.resolveSqlExpression(
createColumnReferenceKey( tableReference, column ),
processingState -> new ColumnReference(

View File

@ -153,7 +153,7 @@ public class AnyKeyPart implements BasicValuedModelPart, FetchOptions {
.getSessionFactory();
final TableGroup tableGroup = fromClauseAccess.getTableGroup( fetchParent.getNavigablePath().getParent() );
final TableReference tableReference = tableGroup.getTableReference( table );
final TableReference tableReference = tableGroup.getTableReference( fetchablePath, table );
final Expression columnReference = sqlExpressionResolver.resolveSqlExpression(
SqlExpressionResolver.createColumnReferenceKey( tableReference, column ),

View File

@ -202,7 +202,7 @@ public class BasicEntityIdentifierMappingImpl implements BasicEntityIdentifierMa
.getSqlExpressionResolver();
final TableReference rootTableReference;
try {
rootTableReference = tableGroup.resolveTableReference( rootTable );
rootTableReference = tableGroup.resolveTableReference( navigablePath, rootTable );
}
catch (Exception e) {
throw new IllegalStateException(

View File

@ -217,7 +217,11 @@ public class BasicValuedSingularAttributeMapping
private SqlSelection resolveSqlSelection(TableGroup tableGroup, DomainResultCreationState creationState) {
final SqlExpressionResolver expressionResolver = creationState.getSqlAstCreationState().getSqlExpressionResolver();
final TableReference tableReference = tableGroup.resolveTableReference( getContainingTableExpression() );
final TableReference tableReference = tableGroup.resolveTableReference(
tableGroup.getNavigablePath()
.append( getNavigableRole().getNavigableName() ),
getContainingTableExpression()
);
final String tableAlias = tableReference.getIdentificationVariable();
return expressionResolver.resolveSqlSelection(
expressionResolver.resolveSqlExpression(

View File

@ -228,12 +228,13 @@ public class EmbeddedAttributeMapping
SqmToSqlAstConverter walker,
SqlAstCreationState sqlAstCreationState) {
final List<ColumnReference> columnReferences = CollectionHelper.arrayList( embeddableMappingType.getJdbcTypeCount() );
final TableReference defaultTableReference = tableGroup.resolveTableReference( getContainingTableExpression() );
final NavigablePath navigablePath = tableGroup.getNavigablePath().append( getNavigableRole().getNavigableName() );
final TableReference defaultTableReference = tableGroup.resolveTableReference( navigablePath, getContainingTableExpression() );
getEmbeddableTypeDescriptor().forEachSelectable(
(columnIndex, selection) -> {
final TableReference tableReference = selection.getContainingTableExpression().equals( defaultTableReference.getTableExpression() )
? defaultTableReference
: tableGroup.resolveTableReference( selection.getContainingTableExpression() );
: tableGroup.resolveTableReference( navigablePath, selection.getContainingTableExpression() );
final Expression columnReference = sqlAstCreationState.getSqlExpressionResolver().resolveSqlExpression(
SqlExpressionResolver.createColumnReferenceKey(
tableReference,
@ -273,6 +274,7 @@ public class EmbeddedAttributeMapping
TableGroup lhs,
String explicitSourceAlias,
SqlAstJoinType sqlAstJoinType,
boolean fetched,
LockMode lockMode,
SqlAliasBaseGenerator aliasBaseGenerator,
SqlExpressionResolver sqlExpressionResolver,

View File

@ -176,7 +176,11 @@ public class EmbeddedCollectionPart implements CollectionPart, EmbeddableValuedF
sqlExpressionResolver.resolveSqlExpression(
SqlExpressionResolver.createColumnReferenceKey( selection.getContainingTableExpression(), selection.getSelectionExpression() ),
sqlAstProcessingState -> new ColumnReference(
tableGroup.resolveTableReference( selection.getContainingTableExpression() ),
tableGroup.resolveTableReference(
tableGroup.getNavigablePath()
.append( getNavigableRole().getNavigableName() ),
selection.getContainingTableExpression()
),
selection,
sqlAstCreationState.getCreationContext().getSessionFactory()
)
@ -193,6 +197,7 @@ public class EmbeddedCollectionPart implements CollectionPart, EmbeddableValuedF
TableGroup lhs,
String explicitSourceAlias,
SqlAstJoinType sqlAstJoinType,
boolean fetched,
LockMode lockMode,
SqlAliasBaseGenerator aliasBaseGenerator,
SqlExpressionResolver sqlExpressionResolver,

View File

@ -245,6 +245,7 @@ public class EmbeddedForeignKeyDescriptor implements ForeignKeyDescriptor {
tableGroup,
null,
SqlAstJoinType.INNER,
true,
LockMode.NONE,
creationState.getSqlAstCreationState()
);
@ -370,7 +371,11 @@ public class EmbeddedForeignKeyDescriptor implements ForeignKeyDescriptor {
return tableGroup.getPrimaryTableReference();
}
final TableReference tableReference = lhs.resolveTableReference( table );
final TableReference tableReference = lhs.resolveTableReference(
lhs.getNavigablePath()
.append( getNavigableRole().getNavigableName() ),
table
);
if ( tableReference != null ) {
return tableReference;
}
@ -407,6 +412,11 @@ public class EmbeddedForeignKeyDescriptor implements ForeignKeyDescriptor {
return keyMappingType.getEmbeddableTypeDescriptor().getEmbeddedValueMapping();
}
@Override
public ModelPart getTargetPart() {
return targetMappingType.getEmbeddableTypeDescriptor().getEmbeddedValueMapping();
}
@Override
public MappingType getPartMappingType() {
return targetMappingType.getPartMappingType();
@ -437,6 +447,7 @@ public class EmbeddedForeignKeyDescriptor implements ForeignKeyDescriptor {
tableGroup,
null,
null,
true,
LockMode.NONE,
creationState.getSqlAstCreationState()
);

View File

@ -151,7 +151,7 @@ public class EntityCollectionPart
final FromClauseAccess fromClauseAccess = creationState.getSqlAstCreationState().getFromClauseAccess();
creationState.registerVisitedAssociationKey( getForeignKeyDescriptor().getAssociationKey() );
fromClauseAccess.resolveTableGroup(
TableGroup tableGroup = fromClauseAccess.resolveTableGroup(
fetchablePath,
np -> {
// We need to create one. The Result will be able to find it later by path
@ -166,7 +166,7 @@ public class EntityCollectionPart
}
);
return new EntityFetchJoinedImpl( fetchParent, this, lockMode, selected, fetchablePath, creationState );
return new EntityFetchJoinedImpl( fetchParent, this, tableGroup, lockMode, selected, fetchablePath, creationState );
}
@Override
@ -347,6 +347,7 @@ public class EntityCollectionPart
TableGroup lhs,
String explicitSourceAlias,
SqlAstJoinType sqlAstJoinType,
boolean fetched,
LockMode lockMode,
SqlAliasBaseGenerator aliasBaseGenerator,
SqlExpressionResolver sqlExpressionResolver,
@ -356,6 +357,7 @@ public class EntityCollectionPart
lhs,
explicitSourceAlias,
sqlAstJoinType,
fetched,
lockMode,
aliasBaseGenerator,
sqlExpressionResolver,

View File

@ -42,7 +42,11 @@ public class EntityDiscriminatorMappingImpl extends AbstractEntityDiscriminatorM
final SqlExpressionResolver expressionResolver = creationState.getSqlAstCreationState()
.getSqlExpressionResolver();
final TableReference tableReference = tableGroup.resolveTableReference( getContainingTableExpression() );
final TableReference tableReference = tableGroup.resolveTableReference(
tableGroup.getNavigablePath()
.append( getNavigableRole().getNavigableName() ),
getContainingTableExpression()
);
return expressionResolver.resolveSqlSelection(
expressionResolver.resolveSqlExpression(

View File

@ -83,7 +83,7 @@ public class EntityRowIdMappingImpl implements EntityRowIdMapping, SelectableMap
final SqlAstCreationState sqlAstCreationState = creationState.getSqlAstCreationState();
final SqlExpressionResolver sqlExpressionResolver = sqlAstCreationState.getSqlExpressionResolver();
final TableReference columnTableReference = tableGroup.resolveTableReference( tableExpression );
final TableReference columnTableReference = tableGroup.resolveTableReference( navigablePath, tableExpression );
final SqlSelection sqlSelection = sqlExpressionResolver.resolveSqlSelection(
sqlExpressionResolver.resolveSqlExpression(

View File

@ -149,7 +149,7 @@ public class EntityVersionMappingImpl implements EntityVersionMapping, FetchOpti
final TableGroup tableGroup = sqlAstCreationState.getFromClauseAccess().findTableGroup( fetchParent.getNavigablePath() );
final SqlExpressionResolver sqlExpressionResolver = sqlAstCreationState.getSqlExpressionResolver();
final TableReference columnTableReference = tableGroup.resolveTableReference( columnTableExpression );
final TableReference columnTableReference = tableGroup.resolveTableReference( fetchablePath, columnTableExpression );
final SqlSelection sqlSelection = sqlExpressionResolver.resolveSqlSelection(
sqlExpressionResolver.resolveSqlExpression(
@ -220,7 +220,11 @@ public class EntityVersionMappingImpl implements EntityVersionMapping, FetchOpti
final SqlAstCreationState sqlAstCreationState = creationState.getSqlAstCreationState();
final SqlExpressionResolver sqlExpressionResolver = sqlAstCreationState.getSqlExpressionResolver();
final TableReference columnTableReference = tableGroup.resolveTableReference( columnTableExpression );
final TableReference columnTableReference = tableGroup.resolveTableReference(
tableGroup.getNavigablePath()
.append( getNavigableRole().getNavigableName() ),
columnTableExpression
);
return sqlExpressionResolver.resolveSqlSelection(
sqlExpressionResolver.resolveSqlExpression(

View File

@ -233,6 +233,7 @@ public class MappingModelCreationHelper {
idAttributeMappings.size(),
bootIdSubProperty,
attributeMappingType,
entityPersister,
keyManyToOnePropertyType,
entityPersister.getRepresentationStrategy().resolvePropertyAccess( bootIdSubProperty ),
CascadeStyles.ALL,
@ -1408,6 +1409,7 @@ public class MappingModelCreationHelper {
int stateArrayPosition,
Property bootProperty,
ManagedMappingType declaringType,
EntityPersister declaringEntityPersister,
EntityType attrType,
PropertyAccess propertyAccess,
CascadeStyle cascadeStyle,
@ -1454,6 +1456,7 @@ public class MappingModelCreationHelper {
fetchStrategy,
entityPersister,
declaringType,
declaringEntityPersister,
propertyAccess
);

View File

@ -417,6 +417,11 @@ public class PluralAttributeMappingImpl
return separateCollectionTable;
}
@Override
public boolean containsTableReference(String tableExpression) {
return tableExpression.equals( separateCollectionTable );
}
@Override
public int getStateArrayPosition() {
return stateArrayPosition;
@ -494,6 +499,7 @@ public class PluralAttributeMappingImpl
lhsTableGroup,
null,
SqlAstJoinType.LEFT,
true,
lockMode,
creationState.getSqlAstCreationState()
);
@ -559,6 +565,7 @@ public class PluralAttributeMappingImpl
TableGroup lhs,
String explicitSourceAlias,
SqlAstJoinType sqlAstJoinType,
boolean fetched,
LockMode lockMode,
SqlAliasBaseGenerator aliasBaseGenerator,
SqlExpressionResolver sqlExpressionResolver,
@ -570,6 +577,7 @@ public class PluralAttributeMappingImpl
lhs,
explicitSourceAlias,
sqlAstJoinType,
fetched,
lockMode,
aliasBaseGenerator,
sqlExpressionResolver,
@ -582,6 +590,7 @@ public class PluralAttributeMappingImpl
lhs,
explicitSourceAlias,
sqlAstJoinType,
fetched,
lockMode,
aliasBaseGenerator,
sqlExpressionResolver,
@ -600,12 +609,14 @@ public class PluralAttributeMappingImpl
TableGroup lhs,
String explicitSourceAlias,
SqlAstJoinType sqlAstJoinType,
boolean fetched,
LockMode lockMode,
SqlAliasBaseGenerator aliasBaseGenerator,
SqlExpressionResolver sqlExpressionResolver,
SqlAstCreationContext creationContext) {
final TableGroup tableGroup = createOneToManyTableGroup(
navigablePath,
fetched,
lockMode,
aliasBaseGenerator,
sqlExpressionResolver,
@ -632,6 +643,7 @@ public class PluralAttributeMappingImpl
private TableGroup createOneToManyTableGroup(
NavigablePath navigablePath,
boolean fetched,
LockMode lockMode,
SqlAliasBaseGenerator aliasBaseGenerator,
SqlExpressionResolver sqlExpressionResolver,
@ -658,6 +670,7 @@ public class PluralAttributeMappingImpl
return new StandardTableGroup(
navigablePath,
this,
fetched,
lockMode,
primaryTableReference,
true,
@ -680,12 +693,14 @@ public class PluralAttributeMappingImpl
TableGroup lhs,
String explicitSourceAlias,
SqlAstJoinType sqlAstJoinType,
boolean fetched,
LockMode lockMode,
SqlAliasBaseGenerator aliasBaseGenerator,
SqlExpressionResolver sqlExpressionResolver,
SqlAstCreationContext creationContext) {
final TableGroup tableGroup = createCollectionTableGroup(
navigablePath,
fetched,
lockMode,
aliasBaseGenerator,
sqlExpressionResolver,
@ -712,6 +727,7 @@ public class PluralAttributeMappingImpl
private TableGroup createCollectionTableGroup(
NavigablePath navigablePath,
boolean fetched,
LockMode lockMode,
SqlAliasBaseGenerator aliasBaseGenerator,
SqlExpressionResolver sqlExpressionResolver,
@ -840,6 +856,7 @@ public class PluralAttributeMappingImpl
final StandardTableGroup tableGroup = new StandardTableGroup(
navigablePath,
this,
fetched,
lockMode,
collectionTableReference,
true,
@ -931,6 +948,7 @@ public class PluralAttributeMappingImpl
if ( getCollectionDescriptor().isOneToMany() ) {
return createOneToManyTableGroup(
navigablePath,
false,
lockMode,
creationState.getSqlAliasBaseGenerator(),
creationState.getSqlExpressionResolver(),
@ -940,6 +958,7 @@ public class PluralAttributeMappingImpl
else {
return createCollectionTableGroup(
navigablePath,
false,
lockMode,
creationState.getSqlAliasBaseGenerator(),
creationState.getSqlExpressionResolver(),

View File

@ -9,12 +9,10 @@ package org.hibernate.metamodel.mapping.internal;
import java.util.Collections;
import java.util.List;
import java.util.Locale;
import java.util.function.BiConsumer;
import java.util.function.Function;
import java.util.function.IntFunction;
import org.hibernate.LockMode;
import org.hibernate.NotYetImplementedFor6Exception;
import org.hibernate.engine.FetchStyle;
import org.hibernate.engine.FetchTiming;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
@ -24,17 +22,13 @@ import org.hibernate.metamodel.mapping.BasicValuedModelPart;
import org.hibernate.metamodel.mapping.EntityMappingType;
import org.hibernate.metamodel.mapping.ForeignKeyDescriptor;
import org.hibernate.metamodel.mapping.JdbcMapping;
import org.hibernate.metamodel.mapping.MappingModelExpressable;
import org.hibernate.metamodel.mapping.MappingType;
import org.hibernate.metamodel.mapping.ModelPart;
import org.hibernate.metamodel.mapping.SelectableConsumer;
import org.hibernate.metamodel.mapping.SelectableMapping;
import org.hibernate.metamodel.mapping.SelectableMappings;
import org.hibernate.metamodel.model.domain.NavigableRole;
import org.hibernate.proxy.HibernateProxy;
import org.hibernate.query.ComparisonOperator;
import org.hibernate.query.NavigablePath;
import org.hibernate.query.sqm.sql.internal.DomainResultProducer;
import org.hibernate.sql.ast.Clause;
import org.hibernate.sql.ast.SqlAstJoinType;
import org.hibernate.sql.ast.spi.SqlAstCreationContext;
@ -94,14 +88,6 @@ public class SimpleForeignKeyDescriptor implements ForeignKeyDescriptor, BasicVa
return targetSide.getContainingTableExpression();
}
public BasicValuedModelPart getKeySide() {
return keySide;
}
public BasicValuedModelPart getTargetSide() {
return targetSide;
}
@Override
public ForeignKeyDescriptor withKeySelectionMapping(
IntFunction<SelectableMapping> selectableMappingAccess,
@ -146,11 +132,7 @@ public class SimpleForeignKeyDescriptor implements ForeignKeyDescriptor, BasicVa
NavigablePath collectionPath,
TableGroup tableGroup,
DomainResultCreationState creationState) {
if ( targetSide.getContainingTableExpression()
.equals( keySide.getContainingTableExpression() ) ) {
return createDomainResult( collectionPath, tableGroup, targetSide, creationState );
}
return createDomainResult( collectionPath, tableGroup, creationState );
return createDomainResult( collectionPath, tableGroup, targetSide, creationState );
}
@Override
@ -204,7 +186,10 @@ public class SimpleForeignKeyDescriptor implements ForeignKeyDescriptor, BasicVa
final SqlAstCreationState sqlAstCreationState = creationState.getSqlAstCreationState();
final SqlExpressionResolver sqlExpressionResolver = sqlAstCreationState.getSqlExpressionResolver();
final TableReference tableReference = tableGroup.resolveTableReference( selectableMapping.getContainingTableExpression() );
final TableReference tableReference = tableGroup.resolveTableReference(
navigablePath.append( getNavigableRole().getNavigableName() ),
selectableMapping.getContainingTableExpression()
);
final String identificationVariable = tableReference.getIdentificationVariable();
final SqlSelection sqlSelection = sqlExpressionResolver.resolveSqlSelection(
@ -333,7 +318,11 @@ public class SimpleForeignKeyDescriptor implements ForeignKeyDescriptor, BasicVa
return tableGroup.getPrimaryTableReference();
}
final TableReference tableReference = lhs.resolveTableReference( table );
final TableReference tableReference = lhs.resolveTableReference(
lhs.getNavigablePath()
.append( getNavigableRole().getNavigableName() ),
table
);
if ( tableReference != null ) {
return tableReference;
}
@ -342,10 +331,15 @@ public class SimpleForeignKeyDescriptor implements ForeignKeyDescriptor, BasicVa
}
@Override
public ModelPart getKeyPart() {
public BasicValuedModelPart getKeyPart() {
return keySide;
}
@Override
public BasicValuedModelPart getTargetPart() {
return targetSide;
}
@Override
public MappingType getPartMappingType() {
return targetSide.getMappedType();

View File

@ -6,6 +6,10 @@
*/
package org.hibernate.metamodel.mapping.internal;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
import org.hibernate.LockMode;
import org.hibernate.engine.FetchStrategy;
import org.hibernate.engine.FetchTiming;
@ -16,14 +20,13 @@ import org.hibernate.mapping.ManyToOne;
import org.hibernate.mapping.OneToOne;
import org.hibernate.mapping.ToOne;
import org.hibernate.metamodel.mapping.AssociationKey;
import org.hibernate.metamodel.mapping.EmbeddableMappingType;
import org.hibernate.metamodel.mapping.CollectionPart;
import org.hibernate.metamodel.mapping.EntityAssociationMapping;
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.SelectableConsumer;
@ -42,15 +45,16 @@ import org.hibernate.sql.ast.spi.SqlAliasStemHelper;
import org.hibernate.sql.ast.spi.SqlAstCreationContext;
import org.hibernate.sql.ast.spi.SqlAstCreationState;
import org.hibernate.sql.ast.spi.SqlExpressionResolver;
import org.hibernate.sql.ast.tree.from.LazyTableGroup;
import org.hibernate.sql.ast.tree.from.StandardTableGroup;
import org.hibernate.sql.ast.tree.from.TableGroup;
import org.hibernate.sql.ast.tree.from.TableGroupJoin;
import org.hibernate.sql.ast.tree.from.TableGroupJoinProducer;
import org.hibernate.sql.ast.tree.from.TableGroupProducer;
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.FetchOptions;
import org.hibernate.sql.results.graph.FetchParent;
import org.hibernate.sql.results.graph.embeddable.EmbeddableValuedFetchable;
import org.hibernate.sql.results.graph.entity.EntityFetch;
@ -63,6 +67,9 @@ 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.type.ComponentType;
import org.hibernate.type.Type;
/**
* @author Steve Ebersole
@ -85,9 +92,12 @@ public class ToOneAttributeMapping
private final EntityMappingType entityMappingType;
private final String referencedPropertyName;
private final String targetKeyPropertyName;
private final Set<String> targetKeyPropertyNames;
private final Cardinality cardinality;
private final String bidirectionalAttributeName;
private final TableGroupProducer declaringTableGroupProducer;
private ForeignKeyDescriptor foreignKeyDescriptor;
private String identifyingColumnsTableExpression;
@ -102,6 +112,7 @@ public class ToOneAttributeMapping
FetchStrategy mappedFetchStrategy,
EntityMappingType entityMappingType,
ManagedMappingType declaringType,
EntityPersister declaringEntityPersister,
PropertyAccess propertyAccess) {
super(
name,
@ -192,6 +203,35 @@ public class ToOneAttributeMapping
}
this.navigableRole = navigableRole;
final CollectionPart.Nature nature = CollectionPart.Nature.fromName(
getNavigableRole().getParent().getLocalName()
);
if ( nature == null ) {
// This is a simple to-one association
this.declaringTableGroupProducer = declaringEntityPersister;
}
else {
// This is a collection part i.e. to-many association
final String collectionRoleName = getNavigableRole().getParent().getParent().getLocalName();
this.declaringTableGroupProducer = ( (PluralAttributeMapping) declaringEntityPersister.findAttributeMapping(
collectionRoleName.substring( collectionRoleName.lastIndexOf( '.' ) + 1 )
) );
}
if ( referencedPropertyName == null ) {
final IdentifierProperty identifierProperty = getEntityMappingType()
.getEntityPersister()
.getEntityMetamodel()
.getIdentifierProperty();
this.targetKeyPropertyName = identifierProperty.getName();
final Set<String> targetKeyPropertyNames = new HashSet<>( 2 );
targetKeyPropertyNames.add( EntityIdentifierMapping.ROLE_LOCAL_NAME );
addPrefixedPropertyNames( targetKeyPropertyNames, targetKeyPropertyName, identifierProperty.getType() );
this.targetKeyPropertyNames = targetKeyPropertyNames;
}
else {
this.targetKeyPropertyName = referencedPropertyName;
this.targetKeyPropertyNames = Collections.singleton( targetKeyPropertyName );
}
}
private ToOneAttributeMapping(ToOneAttributeMapping original) {
@ -209,8 +249,33 @@ public class ToOneAttributeMapping
this.unwrapProxy = original.unwrapProxy;
this.entityMappingType = original.entityMappingType;
this.referencedPropertyName = original.referencedPropertyName;
this.targetKeyPropertyName = original.targetKeyPropertyName;
this.targetKeyPropertyNames = original.targetKeyPropertyNames;
this.cardinality = original.cardinality;
this.bidirectionalAttributeName = original.bidirectionalAttributeName;
this.declaringTableGroupProducer = original.declaringTableGroupProducer;
}
private static void addPrefixedPropertyNames(
Set<String> targetKeyPropertyNames,
String prefix,
Type type) {
if ( type.isComponentType() ) {
targetKeyPropertyNames.add( prefix );
final ComponentType componentType = (ComponentType) type;
final String[] propertyNames = componentType.getPropertyNames();
final Type[] componentTypeSubtypes = componentType.getSubtypes();
for ( int i = 0, propertyNamesLength = propertyNames.length; i < propertyNamesLength; i++ ) {
addPrefixedPropertyNames(
targetKeyPropertyNames,
prefix + "." + propertyNames[i],
componentTypeSubtypes[i]
);
}
}
else {
targetKeyPropertyNames.add( prefix );
}
}
public ToOneAttributeMapping copy() {
@ -233,10 +298,18 @@ public class ToOneAttributeMapping
return this.foreignKeyDescriptor;
}
public boolean canJoinForeignKey(EntityIdentifierMapping identifierMapping) {
return isKeyReferringSide && identifierMapping == getForeignKeyDescriptor().getTargetPart();
}
public String getReferencedPropertyName() {
return referencedPropertyName;
}
public String getTargetKeyPropertyName() {
return targetKeyPropertyName;
}
public Cardinality getCardinality() {
return cardinality;
}
@ -256,6 +329,21 @@ public class ToOneAttributeMapping
return navigableRole;
}
@Override
public ModelPart findSubPart(String name) {
return findSubPart( name, null );
}
@Override
public ModelPart findSubPart(String name, EntityMappingType targetType) {
// Prefer resolving the key part of the foreign key rather than the target part if possible
// This way, we don't have to register table groups the target entity type
if ( name.equals( targetKeyPropertyName ) ) {
return foreignKeyDescriptor.getKeyPart();
}
return EntityValuedFetchable.super.findSubPart( name, targetType );
}
@Override
public Fetch resolveCircularFetch(
NavigablePath fetchablePath,
@ -476,21 +564,23 @@ public class ToOneAttributeMapping
assert parentNavigablePath.equals( fetchParent.getNavigablePath() );
if ( fetchTiming == FetchTiming.IMMEDIATE && selected ) {
final TableGroup tableGroup;
if ( fetchParent instanceof EntityResultJoinedSubclassImpl &&
( (EntityPersister) fetchParent.getReferencedModePart() ).findDeclaredAttributeMapping( getPartName() ) == null ) {
final TableGroup tableGroupJoin = createTableGroupJoin(
tableGroup = createTableGroupJoin(
fetchablePath,
true,
lockMode,
creationState,
parentTableGroup
);
fromClauseAccess.registerTableGroup( fetchablePath, tableGroupJoin );
fromClauseAccess.registerTableGroup( fetchablePath, tableGroup );
}
else {
fromClauseAccess.resolveTableGroup(
tableGroup = fromClauseAccess.resolveTableGroup(
fetchablePath,
np ->
createTableGroupJoin( fetchablePath, lockMode, creationState, parentTableGroup )
createTableGroupJoin( fetchablePath, true, lockMode, creationState, parentTableGroup )
);
}
@ -498,6 +588,7 @@ public class ToOneAttributeMapping
return new EntityFetchJoinedImpl(
fetchParent,
this,
tableGroup,
lockMode,
true,
fetchablePath,
@ -578,6 +669,7 @@ public class ToOneAttributeMapping
tableGroup,
null,
tableGroup.isInnerJoinPossible() ? SqlAstJoinType.INNER : SqlAstJoinType.LEFT,
true,
null,
creationState.getSqlAstCreationState()
);
@ -600,7 +692,7 @@ public class ToOneAttributeMapping
return new EntityResultImpl(
navigablePath,
this,
null,
tableGroup, null,
creationState
);
}
@ -608,6 +700,7 @@ public class ToOneAttributeMapping
private TableGroup createTableGroupJoin(
NavigablePath fetchablePath,
boolean fetched,
LockMode lockMode,
DomainResultCreationState creationState,
TableGroup parentTableGroup) {
@ -628,6 +721,7 @@ public class ToOneAttributeMapping
parentTableGroup,
null,
sqlAstJoinType,
fetched,
lockMode,
creationState.getSqlAstCreationState()
);
@ -646,22 +740,101 @@ public class ToOneAttributeMapping
TableGroup lhs,
String explicitSourceAlias,
SqlAstJoinType sqlAstJoinType,
boolean fetched,
LockMode lockMode,
SqlAliasBaseGenerator aliasBaseGenerator,
SqlExpressionResolver sqlExpressionResolver,
SqlAstCreationContext creationContext) {
final String aliasRoot = explicitSourceAlias == null ? sqlAliasStem : explicitSourceAlias;
final SqlAliasBase sqlAliasBase = aliasBaseGenerator.createSqlAliasBase( aliasRoot );
// We can only use the parent table group if the FK is located there
// If this is false, the FK is on a join table
final boolean canUseParentTableGroup = isKeyReferringSide && declaringTableGroupProducer.containsTableReference(
identifyingColumnsTableExpression );
final LazyTableGroup lazyTableGroup = new LazyTableGroup(
navigablePath,
() -> createTableGroupJoinInternal(
navigablePath,
fetched,
null,
sqlAliasBase,
sqlExpressionResolver,
creationContext
),
np -> {
if ( !canUseParentTableGroup ) {
return false;
}
NavigablePath path = np.getParent();
// Fast path
if ( path != null && navigablePath.equals( path ) ) {
return targetKeyPropertyNames.contains( np.getUnaliasedLocalName() );
}
final StringBuilder sb = new StringBuilder( np.getFullPath().length() );
sb.append( np.getUnaliasedLocalName() );
while ( path != null && !navigablePath.equals( path ) ) {
sb.insert( 0, '.' );
sb.insert( 0, path.getUnaliasedLocalName() );
path = path.getParent();
}
return path != null && navigablePath.equals( path ) && targetKeyPropertyNames.contains(
sb.toString()
);
},
this,
null,
sqlAliasBase,
creationContext.getSessionFactory(),
lhs
);
final TableReference lhsTableReference = lhs.resolveTableReference( navigablePath, identifyingColumnsTableExpression );
final TableGroupJoin tableGroupJoin = new TableGroupJoin(
navigablePath,
sqlAstJoinType,
lazyTableGroup,
null
);
lazyTableGroup.setTableGroupInitializerCallback(
tableGroup -> tableGroupJoin.applyPredicate(
foreignKeyDescriptor.generateJoinPredicate(
lhsTableReference,
tableGroup.getPrimaryTableReference(),
sqlAstJoinType,
sqlExpressionResolver,
creationContext
)
)
);
lhs.addTableGroupJoin( tableGroupJoin );
if ( sqlAstJoinType == SqlAstJoinType.INNER && isNullable ) {
// Force initialization of the underlying table group join to retain cardinality
lazyTableGroup.getPrimaryTableReference();
}
return tableGroupJoin;
}
public TableGroup createTableGroupJoinInternal(
NavigablePath navigablePath,
boolean fetched,
LockMode lockMode,
final SqlAliasBase sqlAliasBase,
SqlExpressionResolver sqlExpressionResolver,
SqlAstCreationContext creationContext) {
final TableReference primaryTableReference = getEntityMappingType().createPrimaryTableReference(
sqlAliasBase,
sqlExpressionResolver,
creationContext
);
final TableGroup tableGroup = new StandardTableGroup(
return new StandardTableGroup(
navigablePath,
this,
fetched,
lockMode,
primaryTableReference,
false,
@ -676,25 +849,6 @@ public class ToOneAttributeMapping
),
creationContext.getSessionFactory()
);
final TableReference lhsTableReference = lhs.resolveTableReference( identifyingColumnsTableExpression );
final TableGroupJoin tableGroupJoin = new TableGroupJoin(
navigablePath,
sqlAstJoinType,
tableGroup,
foreignKeyDescriptor.generateJoinPredicate(
lhsTableReference,
primaryTableReference,
sqlAstJoinType,
sqlExpressionResolver,
creationContext
)
);
lhs.addTableGroupJoin( tableGroupJoin );
return tableGroupJoin;
}
@Override

View File

@ -117,7 +117,7 @@ public class ColumnReference implements OrderingExpression, SequencePart {
final int tableNumber = abstractEntityPersister.determineTableNumberForColumn( columnExpression );
final String tableName = abstractEntityPersister.getTableName( tableNumber );
return tableGroup.getTableReference( tableName );
return tableGroup.getTableReference( tableGroup.getNavigablePath(), tableName );
}
else {
return tableGroup.getPrimaryTableReference();

View File

@ -16,7 +16,6 @@ import org.hibernate.metamodel.model.domain.PluralPersistentAttribute;
import org.hibernate.metamodel.model.domain.SimpleDomainType;
import org.hibernate.query.NavigablePath;
import org.hibernate.query.sqm.SqmPathSource;
import org.hibernate.query.hql.spi.SqmCreationState;
import org.hibernate.query.sqm.internal.SqmMappingModelHelper;
import org.hibernate.query.sqm.tree.domain.SqmPath;
import org.hibernate.query.sqm.tree.domain.SqmPluralValuedSimplePath;
@ -128,14 +127,14 @@ public abstract class AbstractPluralAttribute<D,C,E>
}
@Override
public SqmPath<E> createSqmPath(SqmPath<?> lhs, SqmCreationState creationState) {
public SqmPath<E> createSqmPath(SqmPath<?> lhs) {
final NavigablePath navigablePath = lhs.getNavigablePath().append( getPathName() );
//noinspection unchecked
return new SqmPluralValuedSimplePath(
navigablePath,
this,
lhs,
creationState.getCreationContext().getNodeBuilder()
lhs.nodeBuilder()
);
}
}

View File

@ -6,11 +6,10 @@
*/
package org.hibernate.metamodel.model.domain.internal;
import org.hibernate.NotYetImplementedFor6Exception;
import org.hibernate.metamodel.model.domain.AnyMappingDomainType;
import org.hibernate.metamodel.model.domain.BasicDomainType;
import org.hibernate.query.NavigablePath;
import org.hibernate.query.sqm.SqmPathSource;
import org.hibernate.query.hql.spi.SqmCreationState;
import org.hibernate.query.sqm.tree.domain.SqmAnyValuedSimplePath;
import org.hibernate.query.sqm.tree.domain.SqmPath;
@ -20,7 +19,7 @@ import static javax.persistence.metamodel.Bindable.BindableType.SINGULAR_ATTRIBU
* @author Steve Ebersole
*/
public class AnyMappingSqmPathSource<J> extends AbstractSqmPathSource<J> {
private SqmPathSource<?> keyPathSource;
private final SqmPathSource<?> keyPathSource;
@SuppressWarnings("WeakerAccess")
public AnyMappingSqmPathSource(
@ -47,13 +46,9 @@ public class AnyMappingSqmPathSource<J> extends AbstractSqmPathSource<J> {
}
@Override
public SqmPath<J> createSqmPath(SqmPath<?> lhs, SqmCreationState creationState) {
return new SqmAnyValuedSimplePath<>(
lhs.getNavigablePath().append( getPathName() ),
this,
lhs,
creationState.getCreationContext().getQueryEngine().getCriteriaBuilder()
);
public SqmPath<J> createSqmPath(SqmPath<?> lhs) {
final NavigablePath navigablePath = lhs.getNavigablePath().append( getPathName() );
return new SqmAnyValuedSimplePath( navigablePath, this, lhs, lhs.nodeBuilder() );
}
}

View File

@ -12,7 +12,6 @@ import org.hibernate.metamodel.model.domain.BasicDomainType;
import org.hibernate.query.NavigablePath;
import org.hibernate.query.sqm.IllegalPathUsageException;
import org.hibernate.query.sqm.SqmPathSource;
import org.hibernate.query.hql.spi.SqmCreationState;
import org.hibernate.query.sqm.tree.domain.SqmBasicValuedSimplePath;
import org.hibernate.query.sqm.tree.domain.SqmPath;
@ -42,13 +41,13 @@ public class BasicSqmPathSource<J>
}
@Override
public SqmPath<J> createSqmPath(SqmPath<?> lhs, SqmCreationState creationState) {
public SqmPath<J> createSqmPath(SqmPath<?> lhs) {
final NavigablePath navigablePath = lhs.getNavigablePath().append( getPathName() );
return new SqmBasicValuedSimplePath<>(
navigablePath,
this,
lhs,
creationState.getCreationContext().getNodeBuilder()
lhs.nodeBuilder()
);
}

View File

@ -9,7 +9,6 @@ package org.hibernate.metamodel.model.domain.internal;
import org.hibernate.metamodel.model.domain.AllowableParameterType;
import org.hibernate.metamodel.model.domain.EmbeddableDomainType;
import org.hibernate.query.sqm.SqmPathSource;
import org.hibernate.query.hql.spi.SqmCreationState;
import org.hibernate.query.sqm.tree.domain.SqmEmbeddedValuedSimplePath;
import org.hibernate.query.sqm.tree.domain.SqmPath;
@ -49,12 +48,12 @@ public class EmbeddedSqmPathSource<J>
}
@Override
public SqmPath<J> createSqmPath(SqmPath<?> lhs, SqmCreationState creationState) {
public SqmPath<J> createSqmPath(SqmPath<?> lhs) {
return new SqmEmbeddedValuedSimplePath<>(
lhs.getNavigablePath().append( getPathName() ),
this,
lhs,
creationState.getCreationContext().getNodeBuilder()
lhs.nodeBuilder()
);
}
}

View File

@ -7,7 +7,6 @@
package org.hibernate.metamodel.model.domain.internal;
import org.hibernate.metamodel.model.domain.EntityDomainType;
import org.hibernate.query.hql.spi.SqmCreationState;
import org.hibernate.query.sqm.SqmPathSource;
import org.hibernate.query.sqm.tree.domain.SqmEntityValuedSimplePath;
import org.hibernate.query.sqm.tree.domain.SqmPath;
@ -36,12 +35,12 @@ public class EntitySqmPathSource<J> extends AbstractSqmPathSource<J> {
}
@Override
public SqmPath<J> createSqmPath(SqmPath<?> lhs, SqmCreationState creationState) {
public SqmPath<J> createSqmPath(SqmPath<?> lhs) {
return new SqmEntityValuedSimplePath<>(
lhs.getNavigablePath().append( getPathName() ),
this,
lhs,
creationState.getCreationContext().getNodeBuilder()
lhs.nodeBuilder()
);
}
}

View File

@ -21,7 +21,6 @@ import org.hibernate.metamodel.model.domain.IdentifiableDomainType;
import org.hibernate.metamodel.model.domain.JpaMetamodel;
import org.hibernate.metamodel.model.domain.PersistentAttribute;
import org.hibernate.metamodel.model.domain.SingularPersistentAttribute;
import org.hibernate.query.hql.spi.SqmCreationState;
import org.hibernate.query.sqm.IllegalPathUsageException;
import org.hibernate.query.sqm.SqmPathSource;
import org.hibernate.query.sqm.tree.domain.SqmBasicValuedSimplePath;
@ -86,12 +85,12 @@ public class EntityTypeImpl<J>
}
@Override
public SqmPath<?> createSqmPath(SqmPath lhs, SqmCreationState creationState) {
public SqmPath<?> createSqmPath(SqmPath lhs) {
return new SqmBasicValuedSimplePath(
lhs.getNavigablePath().append( EntityDiscriminatorMapping.ROLE_NAME ),
this,
lhs,
creationState.getCreationContext().getNodeBuilder()
lhs.nodeBuilder()
);
}
@ -223,8 +222,7 @@ public class EntityTypeImpl<J>
@Override
public SqmPath<J> createSqmPath(
SqmPath<?> lhs,
SqmCreationState creationState) {
SqmPath<?> lhs) {
throw new UnsupportedOperationException(
"EntityType cannot be used to create an SqmPath - that would be an SqmFrom which are created directly"
);

View File

@ -6,13 +6,10 @@
*/
package org.hibernate.metamodel.model.domain.internal;
import org.hibernate.NotYetImplementedFor6Exception;
import org.hibernate.metamodel.model.domain.ManagedDomainType;
import org.hibernate.query.hql.spi.SqmCreationState;
import org.hibernate.query.sqm.IllegalPathUsageException;
import org.hibernate.query.sqm.SqmPathSource;
import org.hibernate.query.sqm.tree.domain.NonAggregatedCompositeSimplePath;
import org.hibernate.query.sqm.tree.domain.SqmEmbeddedValuedSimplePath;
import org.hibernate.query.sqm.tree.domain.SqmPath;
/**
@ -39,12 +36,12 @@ public class NonAggregatedCompositeSqmPathSource extends AbstractSqmPathSource i
}
@Override
public SqmPath createSqmPath(SqmPath lhs, SqmCreationState creationState) {
public SqmPath createSqmPath(SqmPath lhs) {
return new NonAggregatedCompositeSimplePath(
lhs.getNavigablePath().append( getPathName() ),
this,
lhs,
creationState.getCreationContext().getNodeBuilder()
lhs.nodeBuilder()
);
}
}

View File

@ -221,10 +221,8 @@ public class SingularAttributeImpl<D,J>
}
@Override
public SqmPath<J> createSqmPath(
SqmPath lhs,
SqmCreationState creationState) {
return sqmPathSource.createSqmPath( lhs, creationState );
public SqmPath<J> createSqmPath(SqmPath lhs) {
return sqmPathSource.createSqmPath( lhs );
}
private class DelayedKeyTypeAccess implements Supplier<SimpleDomainType<J>>, Serializable {

View File

@ -1950,7 +1950,7 @@ public abstract class AbstractCollectionPersister
tableReference = tableGroup.getPrimaryTableReference();
}
else if ( elementPersister instanceof Joinable ) {
tableReference = tableGroup.getTableReference( ( (Joinable) elementPersister ).getTableName() );
tableReference = tableGroup.getTableReference( tableGroup.getNavigablePath(), ( (Joinable) elementPersister ).getTableName() );
}
if ( tableReference != null ) {

View File

@ -1267,7 +1267,7 @@ public abstract class AbstractEntityPersister
String resultVariable,
DomainResultCreationState creationState) {
//noinspection unchecked
return new EntityResultImpl( navigablePath, this, resultVariable, creationState );
return new EntityResultImpl( navigablePath, this, tableGroup, resultVariable, creationState );
}
@Override
@ -6613,6 +6613,7 @@ public abstract class AbstractEntityPersister
stateArrayPosition,
bootProperty,
this,
this,
(EntityType) attrType,
propertyAccess,
tupleAttrDefinition.getCascadeStyle(),

View File

@ -1294,7 +1294,7 @@ public class JoinedSubclassEntityPersister extends AbstractEntityPersister {
DomainResultCreationState creationState) {
if ( hasSubclasses() ) {
//noinspection unchecked
return new EntityResultJoinedSubclassImpl( navigablePath, this, resultVariable, creationState );
return new EntityResultJoinedSubclassImpl( navigablePath, this, tableGroup, resultVariable, creationState );
}
else {
return super.createDomainResult( navigablePath, tableGroup, resultVariable, creationState );
@ -1358,11 +1358,11 @@ public class JoinedSubclassEntityPersister extends AbstractEntityPersister {
boolean addPrimaryTableCaseAsLastCaseExpression = false;
for ( String tableName : discriminatorValuesByTableName.keySet() ) {
if ( !primaryTableReference.getTableExpression().equals( tableName ) ) {
TableReference tableReference = entityTableGroup.getTableReference( tableName );
TableReference tableReference = entityTableGroup.getTableReference( entityTableGroup.getNavigablePath(), tableName );
if ( tableReference == null ) {
// we have not yet created a TableReference for this sub-class table, but we need to because
// it has a discriminator value associated with it
tableReference = entityTableGroup.resolveTableReference( tableName );
tableReference = entityTableGroup.resolveTableReference( entityTableGroup.getNavigablePath(), tableName );
}
final ColumnReference identifierColumnReference = getIdentifierColumnReference( tableReference );

View File

@ -51,9 +51,11 @@ import org.hibernate.sql.ast.spi.SqlAstCreationContext;
import org.hibernate.sql.ast.spi.SqlAstCreationState;
import org.hibernate.sql.ast.spi.SqlExpressionResolver;
import org.hibernate.sql.ast.tree.expression.ColumnReference;
import org.hibernate.sql.ast.tree.expression.Expression;
import org.hibernate.sql.ast.tree.expression.QueryLiteral;
import org.hibernate.sql.ast.tree.from.TableGroup;
import org.hibernate.sql.ast.tree.predicate.ComparisonPredicate;
import org.hibernate.sql.ast.tree.predicate.InListPredicate;
import org.hibernate.sql.ast.tree.predicate.Predicate;
import org.hibernate.type.AssociationType;
import org.hibernate.type.BasicType;
@ -636,7 +638,7 @@ public class SingleTableEntityPersister extends AbstractEntityPersister {
frag.addValues( decodeTreatAsRequests( treatAsDeclarations ) );
}
else {
frag.addValues( fullDiscriminatorValues() );
frag.addValues( fullDiscriminatorSQLValues() );
}
return frag.toFragmentString();
@ -672,10 +674,11 @@ public class SingleTableEntityPersister extends AbstractEntityPersister {
return ArrayHelper.toStringArray( values );
}
private String[] fullDiscriminatorValues;
private String[] fullDiscriminatorSQLValues;
private String[] fullDiscriminatorValues() {
if ( fullDiscriminatorValues == null ) {
private String[] fullDiscriminatorSQLValues() {
String[] fullDiscriminatorSQLValues = this.fullDiscriminatorSQLValues;
if ( fullDiscriminatorSQLValues == null ) {
// first access; build it
final List<String> values = new ArrayList<>();
for ( String subclass : getSubclassClosure() ) {
@ -684,7 +687,26 @@ public class SingleTableEntityPersister extends AbstractEntityPersister {
values.add( queryable.getDiscriminatorSQLValue() );
}
}
fullDiscriminatorValues = ArrayHelper.toStringArray( values );
this.fullDiscriminatorSQLValues = fullDiscriminatorSQLValues = ArrayHelper.toStringArray( values );
}
return fullDiscriminatorSQLValues;
}
private Object[] fullDiscriminatorValues;
private Object[] fullDiscriminatorValues() {
Object[] fullDiscriminatorValues = this.fullDiscriminatorValues;
if ( fullDiscriminatorValues == null ) {
// first access; build it
final List<Object> values = new ArrayList<>();
for ( String subclass : getSubclassClosure() ) {
final Queryable queryable = (Queryable) getFactory().getMetamodel().entityPersister( subclass );
if ( !queryable.isAbstract() ) {
values.add( queryable.getDiscriminatorValue() );
}
}
this.fullDiscriminatorValues = fullDiscriminatorValues = values.toArray(new Object[0]);
}
return fullDiscriminatorValues;
@ -946,23 +968,34 @@ public class SingleTableEntityPersister extends AbstractEntityPersister {
getDiscriminatorColumnName()
);
}
final BasicType<?> discriminatorType = (BasicType<?>) getDiscriminatorType();
final Expression sqlExpression = sqlExpressionResolver.resolveSqlExpression(
columnReferenceKey,
sqlAstProcessingState -> new ColumnReference(
tableGroup.getPrimaryTableReference().getIdentificationVariable(),
discriminatorExpression,
isDiscriminatorFormula(),
null,
null,
(discriminatorType).getJdbcMapping(),
getFactory()
)
);
if ( hasSubclasses() ) {
final Object[] discriminatorValues = fullDiscriminatorValues();
final List<Expression> values = new ArrayList<>( discriminatorValues.length );
for ( Object discriminatorValue : discriminatorValues ) {
values.add( new QueryLiteral<>( discriminatorValue, discriminatorType ) );
}
return new InListPredicate( sqlExpression, values );
}
return new ComparisonPredicate(
sqlExpressionResolver.resolveSqlExpression(
columnReferenceKey,
sqlAstProcessingState -> new ColumnReference(
tableGroup.getPrimaryTableReference().getIdentificationVariable(),
discriminatorExpression,
isDiscriminatorFormula(),
null,
null,
( (BasicType<?>) getDiscriminatorType() ).getJdbcMapping(),
getFactory()
)
),
sqlExpression,
ComparisonOperator.EQUAL,
new QueryLiteral<>(
getDiscriminatorValue(),
( (BasicType<?>) getDiscriminatorType() )
discriminatorType
)
);
}

View File

@ -139,20 +139,12 @@ public class BasicDotIdentifierConsumer implements DotIdentifierConsumer {
}
}
final SqmFrom pathRootByExposedNavigable = sqmPathRegistry.findFromExposing( identifier );
final SqmFrom<?, ?> pathRootByExposedNavigable = sqmPathRegistry.findFromExposing( identifier );
if ( pathRootByExposedNavigable != null ) {
// identifier is an "unqualified attribute reference"
validateAsRoot( pathRootByExposedNavigable );
SqmPath sqmPath = pathRootByExposedNavigable.getImplicitJoinPath( identifier );
if ( sqmPath == null ) {
final SqmPathSource subPathSource = pathRootByExposedNavigable.getReferencedPathSource()
.findSubPathSource( identifier );
sqmPath = subPathSource.createSqmPath( pathRootByExposedNavigable, creationState );
if ( !isTerminal ) {
pathRootByExposedNavigable.registerImplicitJoinPath( sqmPath );
}
}
SqmPath<?> sqmPath = (SqmPath<?>) pathRootByExposedNavigable.get( identifier );
if ( isTerminal ) {
return sqmPath;
}

View File

@ -7,7 +7,6 @@
package org.hibernate.query.hql.internal;
import org.hibernate.NotYetImplementedFor6Exception;
import org.hibernate.query.SemanticException;
import org.hibernate.query.hql.HqlLogging;
import org.hibernate.query.hql.spi.SemanticPathPart;
import org.hibernate.query.hql.spi.SqmCreationState;
@ -43,18 +42,6 @@ public class DomainPathPart implements SemanticPathPart {
currentPath,
name
);
final SqmPath<?> lhs = currentPath;
final SqmPathSource subPathSource = lhs.getReferencedPathSource().findSubPathSource( name );
if ( subPathSource == null ) {
throw new SemanticException( "Cannot resolve path (`" + name + "`) relative to `" + lhs.getNavigablePath() + "`" );
}
//noinspection unchecked
final SqmPath<?> existingImplicitJoinPath = lhs.getImplicitJoinPath( name );
if ( existingImplicitJoinPath != null ) {
currentPath = existingImplicitJoinPath;
return this;
}
// if we want to allow re-use of matched unaliased SqmFrom nodes
//
// final SqmPathRegistry pathRegistry = creationState.getCurrentProcessingState().getPathRegistry();
@ -70,13 +57,11 @@ public class DomainPathPart implements SemanticPathPart {
// }
// }
// }
//
currentPath = subPathSource.createSqmPath( lhs, creationState );
currentPath = (SqmPath<?>) currentPath.get( name );
if ( isTerminal ) {
return currentPath;
}
else {
lhs.registerImplicitJoinPath( currentPath );
return this;
}
}

View File

@ -1925,8 +1925,7 @@ public class SemanticQueryBuilder<R> extends HqlParserBaseVisitor<Object> implem
if ( sqmPathType instanceof IdentifiableDomainType ) {
//noinspection unchecked
final SqmPath idPath = ( (IdentifiableDomainType) sqmPathType ).getIdentifierDescriptor().createSqmPath(
sqmPath,
this
sqmPath
);
if ( ctx.pathContinuation() == null ) {
@ -1960,7 +1959,7 @@ public class SemanticQueryBuilder<R> extends HqlParserBaseVisitor<Object> implem
}
//noinspection unchecked
return versionAttribute.createSqmPath( sqmPath, this );
return versionAttribute.createSqmPath( sqmPath );
}
throw new SemanticException( "Path does not reference an identifiable-type : " + sqmPath.getNavigablePath().getFullPath() );
@ -3832,8 +3831,7 @@ public class SemanticQueryBuilder<R> extends HqlParserBaseVisitor<Object> implem
//noinspection unchecked
return ( (PluralPersistentAttribute<?, ?, ?>) pluralAttribute ).getIndexPathSource().createSqmPath(
sqmFrom,
this
sqmFrom
);
}
@ -4143,8 +4141,7 @@ public class SemanticQueryBuilder<R> extends HqlParserBaseVisitor<Object> implem
//noinspection unchecked
SqmPath result = attribute.getElementPathSource().createSqmPath(
pluralAttributePath,
this
pluralAttributePath
);
if ( ctx.pathContinuation() != null ) {
@ -4162,15 +4159,15 @@ public class SemanticQueryBuilder<R> extends HqlParserBaseVisitor<Object> implem
if ( sqmPath instanceof SqmMapJoin ) {
final SqmMapJoin sqmMapJoin = (SqmMapJoin) sqmPath;
return sqmMapJoin.getReferencedPathSource().getIndexPathSource().createSqmPath( sqmMapJoin, this );
return sqmMapJoin.getReferencedPathSource().getIndexPathSource().createSqmPath( sqmMapJoin );
}
else {
assert sqmPath instanceof SqmPluralValuedSimplePath;
final SqmPluralValuedSimplePath mapPath = (SqmPluralValuedSimplePath) sqmPath;
final SqmPath keyPath = mapPath.getReferencedPathSource()
.getIndexPathSource()
.createSqmPath( mapPath, this );
mapPath.registerImplicitJoinPath( keyPath );
.createSqmPath( mapPath );
mapPath.registerReusablePath( keyPath );
return keyPath;
}
}

View File

@ -29,8 +29,6 @@ import org.hibernate.query.spi.QueryParameterBindings;
import org.hibernate.query.spi.QueryParameterImplementor;
import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
import org.hibernate.type.descriptor.java.JavaTypedExpressable;
import org.hibernate.type.descriptor.java.MutabilityPlan;
import org.hibernate.type.descriptor.java.MutabilityPlanExposer;
import org.hibernate.type.spi.TypeConfiguration;
/**
@ -94,7 +92,7 @@ public class QueryParameterBindingsImpl implements QueryParameterBindings {
}
@SuppressWarnings({"WeakerAccess" })
protected QueryParameterBinding<?> makeBinding(QueryParameterImplementor<?> queryParameter) {
protected <T> QueryParameterBinding<T> makeBinding(QueryParameterImplementor<T> queryParameter) {
if ( parameterBindingMap == null ) {
parameterBindingMap = new IdentityHashMap<>();
}
@ -108,7 +106,7 @@ public class QueryParameterBindingsImpl implements QueryParameterBindings {
);
}
final QueryParameterBinding<?> binding = new QueryParameterBindingImpl<>( queryParameter, sessionFactory, null, queryParametersValidationEnabled );
final QueryParameterBinding<T> binding = new QueryParameterBindingImpl<>( queryParameter, sessionFactory, null, queryParametersValidationEnabled );
parameterBindingMap.put( queryParameter, binding );
return binding;
@ -122,8 +120,7 @@ public class QueryParameterBindingsImpl implements QueryParameterBindings {
@Override
public <P> QueryParameterBinding<P> getBinding(QueryParameterImplementor<P> parameter) {
if ( parameterBindingMap == null ) {
//noinspection unchecked
return (QueryParameterBinding<P>) makeBinding( parameter );
return makeBinding( parameter );
}
QueryParameterBinding<?> binding = parameterBindingMap.get( parameter );

View File

@ -315,7 +315,7 @@ public class DomainResultCreationStateImpl
final Consumer<Fetchable> fetchableConsumer = fetchable -> {
final String fetchableName = fetchable.getFetchableName();
final NavigablePath fetchPath = fetchParent.getNavigablePath().append( fetchableName );
final NavigablePath fetchPath = fetchParent.resolveNavigablePath( fetchable );
final NavigablePath relativePath = relativePathStack.isEmpty()
? new NavigablePath( fetchableName )
: relativePathStack.getCurrent().append( fetchableName );

View File

@ -9,7 +9,6 @@ package org.hibernate.query.results;
import java.util.Collections;
import java.util.List;
import java.util.function.Consumer;
import java.util.function.Supplier;
import org.hibernate.LockMode;
import org.hibernate.engine.spi.SessionFactoryImplementor;
@ -113,18 +112,12 @@ public class TableGroupImpl implements TableGroup {
}
@Override
public TableReference resolveTableReference(
String tableExpression, Supplier<TableReference> creator) {
public TableReference resolveTableReference(NavigablePath navigablePath, String tableExpression) {
return primaryTableReference;
}
@Override
public TableReference resolveTableReference(String tableExpression) {
return primaryTableReference;
}
@Override
public TableReference getTableReference(String tableExpression) {
public TableReference getTableReference(NavigablePath navigablePath, String tableExpression) {
return primaryTableReference;
}

View File

@ -68,7 +68,7 @@ public class CompleteFetchBuilderBasicPart implements CompleteFetchBuilder, Mode
final String mappedColumn = referencedModelPart.getSelectionExpression();
final TableGroup tableGroup = creationState.getFromClauseAccess().getTableGroup( parent.getNavigablePath() );
final TableReference tableReference = tableGroup.getTableReference( mappedTable );
final TableReference tableReference = tableGroup.getTableReference( navigablePath, mappedTable );
final String selectedAlias;
final int jdbcPosition;

View File

@ -62,7 +62,7 @@ public class CompleteResultBuilderBasicModelPart
final DomainResultCreationStateImpl creationStateImpl = impl( domainResultCreationState );
final TableGroup tableGroup = creationStateImpl.getFromClauseAccess().getTableGroup( navigablePath.getParent() );
final TableReference tableReference = tableGroup.getTableReference( modelPart.getContainingTableExpression() );
final TableReference tableReference = tableGroup.getTableReference( navigablePath, modelPart.getContainingTableExpression() );
final String mappedColumn = modelPart.getSelectionExpression();
final int jdbcPosition = jdbcResultsMetadata.resolveColumnPosition( columnAlias );

View File

@ -59,7 +59,7 @@ public class ImplicitFetchBuilderBasic implements ImplicitFetchBuilder {
final int valuesArrayPosition = jdbcPositionToValuesArrayPosition( jdbcPosition );
final Expression expression = creationStateImpl.resolveSqlExpression(
createColumnReferenceKey( parentTableGroup.getTableReference( table ), column ),
createColumnReferenceKey( parentTableGroup.getTableReference( fetchPath, table ), column ),
processingState -> new SqlSelectionImpl( valuesArrayPosition, fetchable )
);

View File

@ -17,13 +17,10 @@ import org.hibernate.query.NavigablePath;
import org.hibernate.query.results.Builders;
import org.hibernate.query.results.DomainResultCreationStateImpl;
import org.hibernate.query.results.FetchBuilder;
import org.hibernate.query.results.SqlSelectionImpl;
import org.hibernate.query.results.dynamic.DynamicFetchBuilderLegacy;
import org.hibernate.sql.ast.SqlAstJoinType;
import org.hibernate.sql.ast.tree.expression.Expression;
import org.hibernate.sql.ast.tree.from.TableGroup;
import org.hibernate.sql.ast.tree.from.TableGroupJoin;
import org.hibernate.sql.ast.tree.from.TableReference;
import org.hibernate.sql.results.graph.DomainResultCreationState;
import org.hibernate.sql.results.graph.Fetch;
import org.hibernate.sql.results.graph.FetchParent;
@ -31,7 +28,6 @@ import org.hibernate.sql.results.graph.embeddable.EmbeddableValuedFetchable;
import org.hibernate.sql.results.jdbc.spi.JdbcValuesMetadata;
import static org.hibernate.query.results.ResultsHelper.impl;
import static org.hibernate.query.results.ResultsHelper.jdbcPositionToValuesArrayPosition;
import static org.hibernate.sql.ast.spi.SqlExpressionResolver.createColumnReferenceKey;
/**
@ -92,6 +88,7 @@ public class ImplicitFetchBuilderEmbeddable implements ImplicitFetchBuilder {
parentTableGroup,
null,
SqlAstJoinType.INNER,
true,
LockMode.READ,
creationStateImpl
);

View File

@ -65,6 +65,7 @@ public class ImplicitModelPartResultBuilderEmbeddable
parentTableGroup,
null,
SqlAstJoinType.INNER,
true,
LockMode.READ,
creationStateImpl
);

View File

@ -720,7 +720,7 @@ public abstract class AbstractQuery<R> implements QueryImplementor<R> {
@SuppressWarnings( {"unchecked", "rawtypes"} )
public Set<Parameter<?>> getParameters() {
getSession().checkOpen( false );
return (Set) ( (ParameterMetadata) getParameterMetadata() ).getRegistrations();
return (Set) getParameterMetadata().getRegistrations();
}
@Override
@ -821,16 +821,16 @@ public abstract class AbstractQuery<R> implements QueryImplementor<R> {
return getQueryParameterBindings().getBinding( parameter );
}
@SuppressWarnings( {"WeakerAccess", "unchecked"} )
@SuppressWarnings( {"WeakerAccess"} )
protected <P> QueryParameterBinding<P> locateBinding(String name) {
getSession().checkOpen();
return (QueryParameterBinding<P>) getQueryParameterBindings().getBinding( name );
return getQueryParameterBindings().getBinding( name );
}
@SuppressWarnings( {"WeakerAccess", "unchecked"} )
@SuppressWarnings( {"WeakerAccess"} )
protected <P> QueryParameterBinding<P> locateBinding(int position) {
getSession().checkOpen();
return (QueryParameterBinding<P>) getQueryParameterBindings().getBinding( position );
return getQueryParameterBindings().getBinding( position );
}
@Override

View File

@ -45,7 +45,7 @@ public interface SqmPathSource<J> extends SqmExpressable<J>, Bindable<J> {
/**
* Create an SQM path for this source relative to the given left-hand side
*/
SqmPath<J> createSqmPath(SqmPath<?> lhs, SqmCreationState creationState);
SqmPath<J> createSqmPath(SqmPath<?> lhs);
default <X extends DomainType> X sqmAs(Class<X> targetType) {
if ( targetType.isInstance( this ) ) {

View File

@ -231,7 +231,9 @@ public class QuerySqmImpl<R>
final Object value = jpaCriteriaParameter.getValue();
// We don't set a null value, unless the type is also null which is the case when using HibernateCriteriaBuilder.value
if ( value != null || jpaCriteriaParameter.getNodeType() == null ) {
setParameter( jpaCriteriaParameter, value );
// Use the anticipated type for binding the value if possible
getQueryParameterBindings().getBinding( jpaCriteriaParameter )
.setBindValue( value, jpaCriteriaParameter.getAnticipatedType() );
}
}
}

View File

@ -87,7 +87,10 @@ public class MatchingIdSelectionHelper {
targetEntityDescriptor.getIdentifierMapping().forEachSelectable(
(position, selection) -> {
final TableReference tableReference = mutatingTableGroup.resolveTableReference( selection.getContainingTableExpression() );
final TableReference tableReference = mutatingTableGroup.resolveTableReference(
mutatingTableGroup.getNavigablePath(),
selection.getContainingTableExpression()
);
final Expression expression = sqmConverter.getSqlExpressionResolver().resolveSqlExpression(
SqlExpressionResolver.createColumnReferenceKey( tableReference, selection.getSelectionExpression() ),
sqlAstProcessingState -> new ColumnReference(
@ -153,7 +156,10 @@ public class MatchingIdSelectionHelper {
targetEntityDescriptor.getIdentifierMapping().forEachSelectable(
(position, selection) -> {
final TableReference tableReference = mutatingTableGroup.resolveTableReference( selection.getContainingTableExpression() );
final TableReference tableReference = mutatingTableGroup.resolveTableReference(
mutatingTableGroup.getNavigablePath(),
selection.getContainingTableExpression()
);
final Expression expression = sqmConverter.getSqlExpressionResolver().resolveSqlExpression(
SqlExpressionResolver.createColumnReferenceKey( tableReference, selection.getSelectionExpression() ),
sqlAstProcessingState -> new ColumnReference(

View File

@ -101,7 +101,10 @@ public class CteDeleteHandler extends AbstractCteMutationHandler implements Dele
idSelectCte.getCteTable().getCteColumns(),
factory
);
final TableReference dmlTableReference = updatingTableGroup.resolveTableReference( tableExpression );
final TableReference dmlTableReference = updatingTableGroup.resolveTableReference(
updatingTableGroup.getNavigablePath(),
tableExpression
);
final List<ColumnReference> columnReferences = new ArrayList<>( idSelectCte.getCteTable().getCteColumns().size() );
tableColumnsVisitationSupplier.get().accept(
(index, selectable) -> columnReferences.add(

View File

@ -69,7 +69,10 @@ public class CteUpdateHandler extends AbstractCteMutationHandler implements Upda
final EntityPersister rootEntityDescriptor = factory.getDomainModel().getEntityDescriptor( rootEntityName );
final String hierarchyRootTableName = ( (Joinable) rootEntityDescriptor ).getTableName();
final TableReference hierarchyRootTableReference = updatingTableGroup.resolveTableReference( hierarchyRootTableName );
final TableReference hierarchyRootTableReference = updatingTableGroup.resolveTableReference(
updatingTableGroup.getNavigablePath(),
hierarchyRootTableName
);
assert hierarchyRootTableReference != null;
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@ -144,7 +147,10 @@ public class CteUpdateHandler extends AbstractCteMutationHandler implements Upda
if ( assignmentList == null ) {
return;
}
final TableReference dmlTableReference = updatingTableGroup.resolveTableReference( tableExpression );
final TableReference dmlTableReference = updatingTableGroup.resolveTableReference(
updatingTableGroup.getNavigablePath(),
tableExpression
);
final List<ColumnReference> columnReferences = new ArrayList<>( idSelectCte.getCteTable().getCteColumns().size() );
tableColumnsVisitationSupplier.get().accept(
(index, selectable) -> columnReferences.add(

View File

@ -87,7 +87,10 @@ public final class ExecuteWithIdTableHelper {
mutatingEntityDescriptor.getIdentifierMapping().forEachSelectable(
(jdbcPosition, selection) -> {
final TableReference tableReference = mutatingTableGroup.resolveTableReference( selection.getContainingTableExpression() );
final TableReference tableReference = mutatingTableGroup.resolveTableReference(
mutatingTableGroup.getNavigablePath(),
selection.getContainingTableExpression()
);
matchingIdSelection.getSelectClause().addSqlSelection(
new SqlSelectionImpl(
jdbcPosition,

View File

@ -124,7 +124,10 @@ public class RestrictedDeleteExecutionDelegate implements TableBasedDeleteHandle
final TableGroup deletingTableGroup = converter.getMutatingTableGroup();
final TableReference hierarchyRootTableReference = deletingTableGroup.resolveTableReference( hierarchyRootTableName );
final TableReference hierarchyRootTableReference = deletingTableGroup.resolveTableReference(
deletingTableGroup.getNavigablePath(),
hierarchyRootTableName
);
assert hierarchyRootTableReference != null;
final Map<SqmParameter, List<List<JdbcParameter>>> parameterResolutions;
@ -213,7 +216,10 @@ public class RestrictedDeleteExecutionDelegate implements TableBasedDeleteHandle
final MutableInteger rows = new MutableInteger();
final String rootTableName = ( (Joinable) rootEntityPersister ).getTableName();
final TableReference rootTableReference = tableGroup.resolveTableReference( rootTableName );
final TableReference rootTableReference = tableGroup.resolveTableReference(
tableGroup.getNavigablePath(),
rootTableName
);
final QuerySpec matchingIdSubQuerySpec = ExecuteWithoutIdTableHelper.createIdMatchingSubQuerySpec(
tableGroup.getNavigablePath(),
@ -251,7 +257,7 @@ public class RestrictedDeleteExecutionDelegate implements TableBasedDeleteHandle
}
else {
deleteFromNonRootTableWithoutIdTable(
tableGroup.resolveTableReference( tableExpression ),
tableGroup.resolveTableReference( tableGroup.getNavigablePath(), tableExpression ),
tableKeyColumnVisitationSupplier,
sqlExpressionResolver,
tableGroup,

View File

@ -133,7 +133,10 @@ public class TableBasedUpdateHandler
final TableGroup updatingTableGroup = converterDelegate.getMutatingTableGroup();
final TableReference hierarchyRootTableReference = updatingTableGroup.resolveTableReference( hierarchyRootTableName );
final TableReference hierarchyRootTableReference = updatingTableGroup.resolveTableReference(
updatingTableGroup.getNavigablePath(),
hierarchyRootTableName
);
assert hierarchyRootTableReference != null;
final Map<SqmParameter, List<List<JdbcParameter>>> parameterResolutions;

View File

@ -211,7 +211,10 @@ public class UpdateExecutionDelegate implements TableBasedUpdateHandler.Executio
return tableReferenceByQualifier;
}
final TableReference tableReferenceByName = updatingTableGroup.resolveTableReference( columnReference.getQualifier() );
final TableReference tableReferenceByName = updatingTableGroup.resolveTableReference(
updatingTableGroup.getNavigablePath(),
columnReference.getQualifier()
);
if ( tableReferenceByName != null ) {
return tableReferenceByName;
}
@ -224,7 +227,7 @@ public class UpdateExecutionDelegate implements TableBasedUpdateHandler.Executio
Supplier<Consumer<SelectableConsumer>> tableKeyColumnVisitationSupplier,
QuerySpec idTableSubQuery,
ExecutionContext executionContext) {
final TableReference updatingTableReference = updatingTableGroup.resolveTableReference( tableExpression );
final TableReference updatingTableReference = updatingTableGroup.resolveTableReference( updatingTableGroup.getNavigablePath(), tableExpression );
final List<Assignment> assignments = assignmentsByTable.get( updatingTableReference );
if ( assignments == null || assignments.isEmpty() ) {

View File

@ -646,11 +646,7 @@ public abstract class BaseSqmToSqlAstConverter<T extends Statement> extends Base
}
private void applyManipulationImplicitJoins(SqmPath<?> sqmPath, TableGroup correspondingTableGroup) {
consumeImplicitJoins(
sqmPath,
correspondingTableGroup,
BaseSqmToSqlAstConverter::verifyManipulationImplicitJoin
);
consumeReusablePaths( sqmPath, correspondingTableGroup, BaseSqmToSqlAstConverter::verifyManipulationImplicitJoin );
}
private static void verifyManipulationImplicitJoin(SqmPath<?> joinedPath) {
@ -1772,7 +1768,7 @@ public abstract class BaseSqmToSqlAstConverter<T extends Statement> extends Base
log.tracef( "Resolved SqmRoot [%s] to correlated TableGroup [%s]", sqmRoot, tableGroup );
consumeExplicitJoins( sqmRoot, tableGroup );
consumeImplicitJoins( sqmRoot, tableGroup );
consumeReusablePaths( sqmRoot, tableGroup );
return;
}
else {
@ -1786,6 +1782,7 @@ public abstract class BaseSqmToSqlAstConverter<T extends Statement> extends Base
creationContext
);
final EntityIdentifierMapping identifierMapping = entityDescriptor.getIdentifierMapping();
final NavigablePath navigablePath = sqmRoot.getNavigablePath().append( identifierMapping.getNavigableRole().getNavigableName() );
final int jdbcTypeCount = identifierMapping.getJdbcTypeCount();
if ( jdbcTypeCount == 1 ) {
identifierMapping.forEachSelectable(
@ -1793,13 +1790,13 @@ public abstract class BaseSqmToSqlAstConverter<T extends Statement> extends Base
additionalRestrictions,
new ComparisonPredicate(
new ColumnReference(
parentTableGroup.getTableReference( selectable.getContainingTableExpression() ),
parentTableGroup.getTableReference( navigablePath, selectable.getContainingTableExpression() ),
selectable,
sessionFactory
),
ComparisonOperator.EQUAL,
new ColumnReference(
tableGroup.getTableReference( selectable.getContainingTableExpression() ),
tableGroup.getTableReference( navigablePath, selectable.getContainingTableExpression() ),
selectable,
sessionFactory
)
@ -1814,14 +1811,14 @@ public abstract class BaseSqmToSqlAstConverter<T extends Statement> extends Base
(index, selectable) -> {
lhs.add(
new ColumnReference(
parentTableGroup.getTableReference( selectable.getContainingTableExpression() ),
parentTableGroup.getTableReference( navigablePath, selectable.getContainingTableExpression() ),
selectable,
sessionFactory
)
);
rhs.add(
new ColumnReference(
tableGroup.getTableReference( selectable.getContainingTableExpression() ),
tableGroup.getTableReference( navigablePath, selectable.getContainingTableExpression() ),
selectable,
sessionFactory
)
@ -1860,7 +1857,7 @@ public abstract class BaseSqmToSqlAstConverter<T extends Statement> extends Base
currentQuerySpec().getFromClause().addRoot( tableGroup );
consumeExplicitJoins( sqmRoot, tableGroup );
consumeImplicitJoins( sqmRoot, tableGroup );
consumeReusablePaths( sqmRoot, tableGroup );
}
private EntityPersister resolveEntityPersister(EntityDomainType<?> entityDomainType) {
@ -1929,6 +1926,7 @@ public abstract class BaseSqmToSqlAstConverter<T extends Statement> extends Base
lhsTableGroup,
sqmJoin.getExplicitAlias(),
sqmJoin.getSqmJoinType().getCorrespondingSqlJoinType(),
sqmJoin.isFetched(),
determineLockMode( sqmJoin.getExplicitAlias() ),
this
);
@ -1943,6 +1941,7 @@ public abstract class BaseSqmToSqlAstConverter<T extends Statement> extends Base
lhsTableGroup,
sqmJoin.getExplicitAlias(),
sqmJoin.getSqmJoinType().getCorrespondingSqlJoinType(),
sqmJoin.isFetched(),
determineLockMode( sqmJoin.getExplicitAlias() ),
this
);
@ -1969,7 +1968,7 @@ public abstract class BaseSqmToSqlAstConverter<T extends Statement> extends Base
}
consumeExplicitJoins( sqmJoin, joinedTableGroup );
consumeImplicitJoins( sqmJoin, joinedTableGroup );
consumeReusablePaths( sqmJoin, joinedTableGroup );
}
private NavigablePath getJoinNavigablePath(
@ -2015,7 +2014,7 @@ public abstract class BaseSqmToSqlAstConverter<T extends Statement> extends Base
getFromClauseIndex().register( sqmJoin, tableGroup );
consumeExplicitJoins( sqmJoin, tableGroupJoin.getJoinedGroup() );
consumeImplicitJoins( sqmJoin, tableGroupJoin.getJoinedGroup() );
consumeReusablePaths( sqmJoin, tableGroupJoin.getJoinedGroup() );
}
private void consumeEntityJoin(SqmEntityJoin sqmJoin, TableGroup lhsTableGroup) {
@ -2043,7 +2042,7 @@ public abstract class BaseSqmToSqlAstConverter<T extends Statement> extends Base
lhsTableGroup.addTableGroupJoin( tableGroupJoin );
consumeExplicitJoins( sqmJoin, tableGroupJoin.getJoinedGroup() );
consumeImplicitJoins( sqmJoin, tableGroupJoin.getJoinedGroup() );
consumeReusablePaths( sqmJoin, tableGroupJoin.getJoinedGroup() );
// add any additional join restrictions
if ( sqmJoin.getJoinPredicate() != null ) {
@ -2054,58 +2053,58 @@ public abstract class BaseSqmToSqlAstConverter<T extends Statement> extends Base
}
private void consumeImplicitJoins(SqmPath<?> sqmPath, TableGroup tableGroup) {
consumeImplicitJoins(
sqmPath,
tableGroup,
(sqmSubPath) -> {}
);
private void consumeReusablePaths(SqmPath<?> sqmPath, TableGroup tableGroup) {
consumeReusablePaths( sqmPath, tableGroup, (sqmSubPath) -> {} );
}
private void consumeImplicitJoins(
private void consumeReusablePaths(
SqmPath<?> sqmPath,
TableGroup tableGroup,
TableGroup parentTableGroup,
Consumer<SqmPath<?>> implicitJoinChecker) {
if ( log.isTraceEnabled() ) {
log.tracef( "Visiting implicit joins for `%s`", sqmPath.getNavigablePath() );
}
sqmPath.visitImplicitJoinPaths(
sqmPath.visitReusablePaths(
joinedPath -> {
if ( log.isTraceEnabled() ) {
log.tracef( "Starting implicit join handling for `%s`", joinedPath.getNavigablePath() );
}
// No need to create a table group for this path if no sub-paths exist
if ( joinedPath.getReusablePaths().isEmpty() ) {
return;
}
implicitJoinChecker.accept( joinedPath );
final SqmPath<?> lhsPath = joinedPath.getLhs();
final FromClauseIndex fromClauseIndex = getFromClauseIndex();
assert fromClauseIndex.findTableGroup( joinedPath.getLhs().getNavigablePath() ) == tableGroup;
final ModelPart subPart = tableGroup.getModelPart().findSubPart(
final ModelPart subPart = parentTableGroup.getModelPart().findSubPart(
joinedPath.getReferencedPathSource().getPathName(),
sqmPath instanceof SqmTreatedPath
? resolveEntityPersister( ( (SqmTreatedPath) sqmPath ).getTreatTarget() )
lhsPath instanceof SqmTreatedPath
? resolveEntityPersister( ( (SqmTreatedPath<?, ?>) lhsPath ).getTreatTarget() )
: null
);
final TableGroup tableGroup;
if ( subPart instanceof TableGroupJoinProducer ) {
implicitJoinChecker.accept( joinedPath );
final TableGroupJoinProducer joinProducer = (TableGroupJoinProducer) subPart;
final TableGroupJoin tableGroupJoin = joinProducer.createTableGroupJoin(
joinedPath.getNavigablePath(),
tableGroup,
parentTableGroup,
null,
tableGroup.isInnerJoinPossible() ? SqlAstJoinType.INNER : SqlAstJoinType.LEFT,
parentTableGroup.isInnerJoinPossible() ? SqlAstJoinType.INNER : SqlAstJoinType.LEFT,
false,
null,
this
);
fromClauseIndex.register( joinedPath, tableGroupJoin.getJoinedGroup() );
consumeImplicitJoins( joinedPath, tableGroupJoin.getJoinedGroup(), implicitJoinChecker );
tableGroup = tableGroupJoin.getJoinedGroup();
}
else {
fromClauseIndex.register( joinedPath, tableGroup );
tableGroup = null;
}
consumeReusablePaths( joinedPath, tableGroup, implicitJoinChecker );
}
);
}
@ -2555,7 +2554,7 @@ public abstract class BaseSqmToSqlAstConverter<T extends Statement> extends Base
if ( sqmParameter.getAnticipatedType() == null ) {
// this should indicate the condition that the user query did not define an
// explicit type in regard to this parameter. Here we should prefer the
// inferable type and fallback to the binding type
// inferrable type and fallback to the binding type
final Supplier<MappingModelExpressable> currentExpressableSupplier = inferrableTypeAccessStack.getCurrent();
if ( currentExpressableSupplier != null ) {
final MappingModelExpressable inferredMapping = currentExpressableSupplier.get();
@ -2697,6 +2696,7 @@ public abstract class BaseSqmToSqlAstConverter<T extends Statement> extends Base
parentTableGroup,
null,
SqlAstJoinType.INNER,
false,
LockMode.READ,
sqlAliasBaseManager,
getSqlExpressionResolver(),
@ -3907,12 +3907,12 @@ public abstract class BaseSqmToSqlAstConverter<T extends Statement> extends Base
? mappingModelExpressable.getIndexDescriptor()
: mappingModelExpressable.getElementDescriptor();
final List<SqlAstNode> arguments = new ArrayList<>( 1 );
final NavigablePath navigablePath = pluralPartPath.getNavigablePath();
collectionPart.forEachSelectable(
(selectionIndex, selectionMapping) -> {
arguments.add(
new ColumnReference(
tableGroup.getTableReference( selectionMapping.getContainingTableExpression() ),
tableGroup.getTableReference( navigablePath, selectionMapping.getContainingTableExpression() ),
selectionMapping,
creationContext.getSessionFactory()
)
@ -4150,6 +4150,7 @@ public abstract class BaseSqmToSqlAstConverter<T extends Statement> extends Base
tableGroup,
sqmPluralPath.getExplicitAlias(),
SqlAstJoinType.INNER,
false,
LockMode.NONE,
sqlAliasBaseManager,
subQueryState,
@ -4451,7 +4452,7 @@ public abstract class BaseSqmToSqlAstConverter<T extends Statement> extends Base
final List<String> bagRoles = new ArrayList<>();
final BiConsumer<Fetchable, Boolean> fetchableBiConsumer = (fetchable, isKeyFetchable) -> {
final NavigablePath fetchablePath = fetchParent.getNavigablePath().append( fetchable.getFetchableName() );
final NavigablePath fetchablePath = fetchParent.resolveNavigablePath( fetchable );
final Fetch biDirectionalFetch = fetchable.resolveCircularFetch(
fetchablePath,
@ -4594,6 +4595,7 @@ public abstract class BaseSqmToSqlAstConverter<T extends Statement> extends Base
lhs,
alias,
SqlAstJoinType.LEFT,
true,
LockMode.NONE,
this
);

View File

@ -46,7 +46,10 @@ public class BasicValuedPathInterpretation<T> extends AbstractSqmPathInterpretat
throw new SemanticException( "`" + sqmPath.getNavigablePath().getFullPath() + "` did not reference a known model part" );
}
final TableReference tableReference = tableGroup.resolveTableReference( mapping.getContainingTableExpression() );
final TableReference tableReference = tableGroup.resolveTableReference(
sqmPath.getNavigablePath(),
mapping.getContainingTableExpression()
);
final Expression expression = sqlAstCreationState.getSqlExpressionResolver().resolveSqlExpression(
SqlExpressionResolver.createColumnReferenceKey(

View File

@ -43,7 +43,7 @@ public class DiscriminatedAssociationPathInterpretation<T> extends AbstractSqmPa
mapping.forEachSelectable(
(selectionIndex, selectableMapping) -> {
final TableReference tableReference = tableGroup.resolveTableReference( selectableMapping.getContainingTableExpression() );
final TableReference tableReference = tableGroup.resolveTableReference( sqmPath.getNavigablePath(), selectableMapping.getContainingTableExpression() );
final Expression expression = converter.getSqlExpressionResolver().resolveSqlExpression(
SqlExpressionResolver.createColumnReferenceKey( tableReference, selectableMapping.getSelectionExpression() ),
processingState -> new ColumnReference(

View File

@ -61,7 +61,10 @@ public class EntityValuedPathInterpretation<T> extends AbstractSqmPathInterpreta
if ( mapping instanceof EntityAssociationMapping ) {
final EntityAssociationMapping associationMapping = (EntityAssociationMapping) mapping;
final ForeignKeyDescriptor keyDescriptor = associationMapping.getForeignKeyDescriptor();
final TableReference tableReference = tableGroup.resolveTableReference( keyDescriptor.getKeyTable() );
final TableReference tableReference = tableGroup.resolveTableReference(
sqmPath.getNavigablePath(),
keyDescriptor.getKeyTable()
);
if ( keyDescriptor instanceof SimpleForeignKeyDescriptor ) {
final SimpleForeignKeyDescriptor simpleKeyDescriptor = (SimpleForeignKeyDescriptor) keyDescriptor;
@ -98,7 +101,10 @@ public class EntityValuedPathInterpretation<T> extends AbstractSqmPathInterpreta
if ( identifierMapping instanceof BasicEntityIdentifierMapping ) {
final BasicEntityIdentifierMapping simpleIdMapping = (BasicEntityIdentifierMapping) identifierMapping;
final TableReference tableReference = tableGroup.resolveTableReference( simpleIdMapping.getContainingTableExpression() );
final TableReference tableReference = tableGroup.resolveTableReference(
sqmPath.getNavigablePath(),
simpleIdMapping.getContainingTableExpression()
);
assert tableReference != null : "Could not resolve table-group : " + simpleIdMapping.getContainingTableExpression();
sqlExpression = sqlExprResolver.resolveSqlExpression(
@ -189,6 +195,7 @@ public class EntityValuedPathInterpretation<T> extends AbstractSqmPathInterpreta
parentTableGroup,
null,
SqlAstJoinType.INNER,
false,
LockMode.READ,
sqlAstCreationState
);

View File

@ -121,7 +121,7 @@ public abstract class AbstractSqmFrom<O,T> extends AbstractSqmPath<T> implements
throw UnknownPathException.unknownSubPath( this, name );
}
return subSource.createSqmPath( this, creationState );
return subSource.createSqmPath( this );
}
);
}

View File

@ -10,9 +10,7 @@ import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.function.BiFunction;
import java.util.function.Consumer;
import javax.persistence.metamodel.MapAttribute;
import javax.persistence.metamodel.PluralAttribute;
@ -21,11 +19,8 @@ import javax.persistence.metamodel.SingularAttribute;
import org.hibernate.metamodel.mapping.EntityDiscriminatorMapping;
import org.hibernate.metamodel.model.domain.DomainType;
import org.hibernate.metamodel.model.domain.EntityDomainType;
import org.hibernate.metamodel.model.domain.MapPersistentAttribute;
import org.hibernate.metamodel.model.domain.PluralPersistentAttribute;
import org.hibernate.metamodel.model.domain.SingularPersistentAttribute;
import org.hibernate.metamodel.model.domain.PersistentAttribute;
import org.hibernate.query.NavigablePath;
import org.hibernate.query.hql.spi.SqmCreationState;
import org.hibernate.query.sqm.IllegalPathUsageException;
import org.hibernate.query.sqm.NodeBuilder;
import org.hibernate.query.sqm.SqmPathSource;
@ -39,23 +34,14 @@ import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
*/
public abstract class AbstractSqmPath<T> extends AbstractSqmExpression<T> implements SqmPath<T> {
private final NavigablePath navigablePath;
private final SqmPath lhs;
private final SqmPath<?> lhs;
/**
* Note that this field is only really used to support Criteria building.
* For HQL processing the {@link org.hibernate.query.hql.spi.SqmPathRegistry}
* serves the same purpose.
* For HQL and Criteria processing - used to track reusable paths relative to this path.
* E.g., given `p.mate.mate` the SqmRoot identified by `p` would
* have a reusable path for the `p.mate` path.
*/
private Map<String, SqmPath> attributePathRegistry;
/**
* For HQL processing - used to track implicit-join paths relative to this
* path. E.g., given `p.mate.mate` the SqmRoot identified by `p` would
* have an implicit-join for the `p.mate` path. Note however that the SqmPath
* for `p.mate` would not have one for `p.mate.mate` *unless* `p.mate.mate` were
* de-referenced somewhere else in the query.
*/
private Map<String,SqmPath<?>> implicitJoinPaths;
private Map<String, SqmPath<?>> reusablePaths;
@SuppressWarnings("WeakerAccess")
protected AbstractSqmPath(
@ -79,7 +65,7 @@ public abstract class AbstractSqmPath<T> extends AbstractSqmExpression<T> implem
}
@SuppressWarnings("WeakerAccess")
protected AbstractSqmPath(SqmPathSource<T> referencedPathSource, SqmPath lhs, NodeBuilder nodeBuilder) {
protected AbstractSqmPath(SqmPathSource<T> referencedPathSource, SqmPath<?> lhs, NodeBuilder nodeBuilder) {
this(
lhs == null
? new NavigablePath( referencedPathSource.getPathName() )
@ -101,43 +87,43 @@ public abstract class AbstractSqmPath<T> extends AbstractSqmExpression<T> implem
}
@Override
public List<SqmPath<?>> getImplicitJoinPaths() {
if ( implicitJoinPaths == null ) {
public List<SqmPath<?>> getReusablePaths() {
if ( reusablePaths == null ) {
return Collections.emptyList();
}
return new ArrayList<>( implicitJoinPaths.values() );
return new ArrayList<>( reusablePaths.values() );
}
@Override
public void visitImplicitJoinPaths(Consumer<SqmPath<?>> consumer) {
if ( implicitJoinPaths != null ) {
implicitJoinPaths.values().forEach( consumer );
public void visitReusablePaths(Consumer<SqmPath<?>> consumer) {
if ( reusablePaths != null ) {
reusablePaths.values().forEach( consumer );
}
}
@Override
public void registerImplicitJoinPath(SqmPath<?> path) {
public void registerReusablePath(SqmPath<?> path) {
assert path.getLhs() == this;
if ( implicitJoinPaths == null ) {
implicitJoinPaths = new HashMap<>();
if ( reusablePaths == null ) {
reusablePaths = new HashMap<>();
}
final String relativeName = path.getNavigablePath().getLocalName();
final SqmPath<?> previous = implicitJoinPaths.put( relativeName, path );
final SqmPath<?> previous = reusablePaths.put( relativeName, path );
if ( previous != null && previous != path ) {
throw new IllegalStateException( "Implicit-join path registration unexpectedly overrode previous registration - " + relativeName );
}
}
@Override
public SqmPath<?> getImplicitJoinPath(String name) {
if ( implicitJoinPaths == null ) {
public SqmPath<?> getReusablePath(String name) {
if ( reusablePaths == null ) {
return null;
}
return implicitJoinPaths.get( name );
return reusablePaths.get( name );
}
@Override
@ -185,7 +171,7 @@ public abstract class AbstractSqmPath<T> extends AbstractSqmExpression<T> implem
}
@Override
public SqmPath createSqmPath(SqmPath lhs, SqmCreationState creationState) {
public SqmPath createSqmPath(SqmPath lhs) {
return new SqmBasicValuedSimplePath( discriminatorNavigablePath, this, AbstractSqmPath.this, nodeBuilder() );
}
@ -195,7 +181,7 @@ public abstract class AbstractSqmPath<T> extends AbstractSqmExpression<T> implem
}
@Override
public Class getBindableJavaType() {
public Class<?> getBindableJavaType() {
return null;
}
@ -234,111 +220,49 @@ public abstract class AbstractSqmPath<T> extends AbstractSqmExpression<T> implem
throw new IllegalStateException( "Cannot resolve path `" + attributeName + "` relative to a basic-valued path: `" + getNavigablePath() + "`" );
}
return resolvePath(
attributeName,
(pathSource, name) -> {
final SqmPathSource<?> subNavigable = getReferencedPathSource().findSubPathSource( attributeName );
final SqmPathSource<?> subNavigable = getReferencedPathSource().findSubPathSource( attributeName );
if ( subNavigable == null ) {
throw new IllegalArgumentException( "Could not resolve attribute named `" + attributeName + "` relative to `" + getNavigablePath() + "`" );
}
if ( subNavigable instanceof SingularPersistentAttribute ) {
return createSingularPath( (SingularPersistentAttribute<?,?>) subNavigable );
}
else {
assert subNavigable instanceof PluralPersistentAttribute;
return createPluralPath( (PluralPersistentAttribute<?,?,?>) subNavigable );
}
}
);
}
@SuppressWarnings("unchecked")
private SqmPath createSingularPath(SingularPersistentAttribute attribute) {
final NavigablePath subNavPath = getNavigablePath().append( attribute.getPathName() );
switch ( attribute.getAttributeClassification() ) {
case BASIC: {
return new SqmBasicValuedSimplePath( subNavPath, attribute, this, nodeBuilder() );
}
case EMBEDDED: {
return new SqmEmbeddedValuedSimplePath( subNavPath, attribute, this, nodeBuilder() );
}
case ANY: {
return new SqmAnyValuedSimplePath( subNavPath, attribute, this, nodeBuilder() );
}
case ONE_TO_ONE:
case MANY_TO_ONE: {
return new SqmEntityValuedSimplePath( subNavPath, attribute, this, nodeBuilder() );
}
default: {
throw new UnsupportedOperationException(
String.format(
Locale.ROOT,
"Cannot create SqmPath from singular attribute [%s#%s] - unknown classification : %s",
attribute.getDeclaringType().getTypeName(),
attribute.getName(),
attribute.getAttributeClassification()
)
);
}
if ( subNavigable == null ) {
throw new IllegalArgumentException( "Could not resolve attribute named `" + attributeName + "` relative to `" + getNavigablePath() + "`" );
}
return resolvePath( attributeName, subNavigable );
}
private SqmPath createPluralPath(PluralPersistentAttribute pluralAttribute) {
return new SqmPluralValuedSimplePath(
getNavigablePath().append( pluralAttribute.getPathName() ),
pluralAttribute,
this,
nodeBuilder()
);
private SqmPath<?> resolvePath(PersistentAttribute<?, ?> attribute) {
return resolvePath( attribute.getName(), (SqmPathSource<?>) attribute );
}
private SqmPath resolvePath(String attributeName, BiFunction<SqmPath, String, SqmPath> creator) {
final SqmPath pathSource = getLhs();
if ( attributePathRegistry == null ) {
attributePathRegistry = new HashMap<>();
final SqmPath path = creator.apply( pathSource, attributeName );
attributePathRegistry.put( attributeName, path );
private SqmPath<?> resolvePath(String attributeName, SqmPathSource<?> pathSource) {
if ( reusablePaths == null ) {
reusablePaths = new HashMap<>();
final SqmPath<?> path = pathSource.createSqmPath( this );
reusablePaths.put( attributeName, path );
return path;
}
else {
return attributePathRegistry.computeIfAbsent(
return reusablePaths.computeIfAbsent(
attributeName,
name -> creator.apply( pathSource, attributeName )
name -> pathSource.createSqmPath( this )
);
}
}
@Override
@SuppressWarnings("unchecked")
public SqmPath get(SingularAttribute jpaAttribute) {
final SingularPersistentAttribute attribute = (SingularPersistentAttribute) jpaAttribute;
return resolvePath(
attribute.getName(),
(pathSource, name) -> createSingularPath( attribute )
);
public <Y> SqmPath<Y> get(SingularAttribute<? super T, Y> jpaAttribute) {
return (SqmPath<Y>) resolvePath( (PersistentAttribute<?, ?>) jpaAttribute );
}
@Override
@SuppressWarnings("unchecked")
public SqmPath get(PluralAttribute attribute) {
return resolvePath(
attribute.getName(),
(pathSource, name) -> createPluralPath( (PluralPersistentAttribute) attribute )
);
public <E, C extends java.util.Collection<E>> SqmPath<C> get(PluralAttribute<T, C, E> attribute) {
return (SqmPath<C>) resolvePath( (PersistentAttribute<?, ?>) attribute );
}
@Override
@SuppressWarnings("unchecked")
public SqmPath get(MapAttribute map) {
return resolvePath(
map.getName(),
(pathSource, name) -> createPluralPath( (MapPersistentAttribute) map )
);
public <K, V, M extends java.util.Map<K, V>> SqmPath<M> get(MapAttribute<T, K, V> map) {
return (SqmPath<M>) resolvePath( (PersistentAttribute<?, ?>) map );
}
@Override

View File

@ -43,7 +43,7 @@ public class NonAggregatedCompositeSimplePath<T> extends SqmEntityValuedSimplePa
throw UnknownPathException.unknownSubPath( this, name );
}
return subPathSource.createSqmPath( this, creationState );
return subPathSource.createSqmPath( this );
}
@Override

View File

@ -25,7 +25,7 @@ public class SqmAnyValuedSimplePath<T> extends AbstractSqmSimplePath<T> {
public SqmAnyValuedSimplePath(
NavigablePath navigablePath,
SqmPathSource<T> referencedPathSource,
SqmPath lhs,
SqmPath<?> lhs,
NodeBuilder nodeBuilder) {
super( navigablePath, referencedPathSource, lhs, nodeBuilder );
@ -36,7 +36,7 @@ public class SqmAnyValuedSimplePath<T> extends AbstractSqmSimplePath<T> {
public SqmAnyValuedSimplePath(
NavigablePath navigablePath,
SqmPathSource<T> referencedPathSource,
SqmPath lhs,
SqmPath<?> lhs,
String explicitAlias,
NodeBuilder nodeBuilder) {
super( navigablePath, referencedPathSource, lhs, explicitAlias, nodeBuilder );
@ -64,7 +64,7 @@ public class SqmAnyValuedSimplePath<T> extends AbstractSqmSimplePath<T> {
throw UnknownPathException.unknownSubPath( this, name );
}
return subPathSource.createSqmPath( this, creationState );
return subPathSource.createSqmPath( this );
}

View File

@ -6,6 +6,7 @@
*/
package org.hibernate.query.sqm.tree.domain;
import org.hibernate.metamodel.model.domain.AllowableParameterType;
import org.hibernate.metamodel.model.domain.EmbeddableDomainType;
import org.hibernate.metamodel.model.domain.EntityDomainType;
import org.hibernate.query.NavigablePath;
@ -16,11 +17,12 @@ import org.hibernate.query.sqm.SqmPathSource;
import org.hibernate.query.sqm.UnknownPathException;
import org.hibernate.query.sqm.SemanticQueryWalker;
import org.hibernate.query.hql.spi.SqmCreationState;
import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
/**
* @author Steve Ebersole
*/
public class SqmEmbeddedValuedSimplePath<T> extends AbstractSqmSimplePath<T> {
public class SqmEmbeddedValuedSimplePath<T> extends AbstractSqmSimplePath<T> implements AllowableParameterType<T> {
public SqmEmbeddedValuedSimplePath(
NavigablePath navigablePath,
SqmPathSource<T> referencedPathSource,
@ -53,7 +55,7 @@ public class SqmEmbeddedValuedSimplePath<T> extends AbstractSqmSimplePath<T> {
throw UnknownPathException.unknownSubPath( this, name );
}
return subPathSource.createSqmPath( this, creationState );
return subPathSource.createSqmPath( this );
}
@Override
@ -72,7 +74,22 @@ public class SqmEmbeddedValuedSimplePath<T> extends AbstractSqmSimplePath<T> {
throw new PathException( "Embeddable paths cannot be TREAT-ed" );
}
// @Override
@Override
public JavaTypeDescriptor<T> getExpressableJavaTypeDescriptor() {
return getJavaTypeDescriptor();
}
@Override
public PersistenceType getPersistenceType() {
return PersistenceType.EMBEDDABLE;
}
@Override
public Class<T> getJavaType() {
return getJavaTypeDescriptor().getJavaTypeClass();
}
// @Override
// public DomainResult createDomainResult(
// String resultVariable,
// DomainResultCreationState creationState,

View File

@ -41,7 +41,7 @@ public class SqmEntityValuedSimplePath<T> extends AbstractSqmSimplePath<T> {
.findPath( getLhs().getNavigablePath() ) != null;
//noinspection unchecked
return subPathSource.createSqmPath( this, creationState );
return subPathSource.createSqmPath( this );
}
@Override

View File

@ -61,7 +61,7 @@ public class SqmIndexedCollectionAccessPath<T> extends AbstractSqmPath<T> implem
SqmCreationState creationState) {
final SqmPathSource subPathSource = getReferencedPathSource().getElementPathSource().findSubPathSource( name );
//noinspection unchecked
return subPathSource.createSqmPath( this, creationState );
return subPathSource.createSqmPath( this );
}
@Override

View File

@ -36,7 +36,7 @@ public class SqmMaxElementPath<T> extends AbstractSqmSpecificPluralPartPath<T> {
SqmCreationState creationState) {
if ( getPluralAttribute().getElementPathSource().getSqmPathType() instanceof ManagedDomainType ) {
//noinspection unchecked
return getPluralAttribute().getElementPathSource().createSqmPath( this, creationState );
return getPluralAttribute().getElementPathSource().createSqmPath( this );
}
throw new SemanticException( "Collection element cannot be de-referenced : " + getPluralDomainPath().getNavigablePath() );

View File

@ -48,7 +48,7 @@ public class SqmMaxIndexPath<T> extends AbstractSqmSpecificPluralPartPath<T> {
String name,
boolean isTerminal,
SqmCreationState creationState) {
return indexPathSource.createSqmPath( this, creationState );
return indexPathSource.createSqmPath( this );
}
@Override

View File

@ -36,7 +36,7 @@ public class SqmMinElementPath<T> extends AbstractSqmSpecificPluralPartPath<T> {
SqmCreationState creationState) {
if ( getPluralAttribute().getElementPathSource().getSqmPathType() instanceof ManagedDomainType ) {
//noinspection unchecked
return getPluralAttribute().getElementPathSource().createSqmPath( this, creationState );
return getPluralAttribute().getElementPathSource().createSqmPath( this );
}
throw new SemanticException( "Collection element cannot be de-referenced : " + getPluralDomainPath().getNavigablePath() );

View File

@ -48,7 +48,7 @@ public class SqmMinIndexPath<T> extends AbstractSqmSpecificPluralPartPath<T> {
String name,
boolean isTerminal,
SqmCreationState creationState) {
return indexPathSource.createSqmPath( this, creationState );
return indexPathSource.createSqmPath( this );
}
@Override

View File

@ -63,21 +63,21 @@ public interface SqmPath<T> extends SqmExpression<T>, SemanticPathPart, JpaPath<
SqmPath<?> getLhs();
/**
* Returns an immutable List of implicit-join paths
* Returns an immutable List of reusable paths
*/
List<SqmPath<?>> getImplicitJoinPaths();
List<SqmPath<?>> getReusablePaths();
/**
* Visit each implicit-join path relative to this path
* Visit each reusable path relative to this path
*/
void visitImplicitJoinPaths(Consumer<SqmPath<?>> consumer);
void visitReusablePaths(Consumer<SqmPath<?>> consumer);
/**
* Register an implicit-join path relative to this path
* Register a reusable path relative to this path
*/
void registerImplicitJoinPath(SqmPath<?> path);
void registerReusablePath(SqmPath<?> path);
SqmPath<?> getImplicitJoinPath(String name);
SqmPath<?> getReusablePath(String name);
/**
* This node's type is its "referenced path source"

View File

@ -86,26 +86,24 @@ public class SqmPluralValuedSimplePath<E> extends AbstractSqmSimplePath<E> {
if ( CollectionPropertyNames.COLLECTION_ELEMENTS.equals( name ) ) {
return referencedPathSource.getElementPathSource().createSqmPath(
this,
creationState
this
);
}
if ( CollectionPropertyNames.COLLECTION_INDEX.equals( name )
|| CollectionPropertyNames.COLLECTION_INDICES.equals( name ) ) {
if ( referencedPathSource instanceof MapPersistentAttribute ) {
return ( (MapPersistentAttribute) referencedPathSource ).getKeyPathSource().createSqmPath( this, creationState );
return ( (MapPersistentAttribute) referencedPathSource ).getKeyPathSource().createSqmPath( this );
}
else if ( referencedPathSource instanceof ListPersistentAttribute ) {
return referencedPathSource.getIndexPathSource().createSqmPath( this, creationState );
return referencedPathSource.getIndexPathSource().createSqmPath( this );
}
throw new UnsupportedOperationException( );
}
return referencedPathSource.getElementPathSource().createSqmPath(
this,
creationState
this
);
}
);

View File

@ -33,7 +33,6 @@ import org.hibernate.metamodel.model.domain.PersistentAttribute;
import org.hibernate.metamodel.model.domain.PluralPersistentAttribute;
import org.hibernate.metamodel.model.domain.SimpleDomainType;
import org.hibernate.metamodel.model.domain.SingularPersistentAttribute;
import org.hibernate.query.hql.spi.SqmCreationState;
import org.hibernate.query.sqm.SqmPathSource;
import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
@ -374,7 +373,7 @@ public class SqmPolymorphicRootDescriptor<T> implements EntityDomainType<T> {
}
@Override
public SqmPath<T> createSqmPath(SqmPath<?> lhs, SqmCreationState creationState) {
public SqmPath<T> createSqmPath(SqmPath<?> lhs) {
throw new UnsupportedOperationException();
}

View File

@ -12,6 +12,7 @@ import org.hibernate.sql.ast.tree.SqlAstTreeLogger;
import org.hibernate.sql.ast.tree.Statement;
import org.hibernate.sql.ast.tree.delete.DeleteStatement;
import org.hibernate.sql.ast.tree.from.FromClause;
import org.hibernate.sql.ast.tree.from.LazyTableGroup;
import org.hibernate.sql.ast.tree.from.TableGroup;
import org.hibernate.sql.ast.tree.from.TableGroupJoin;
import org.hibernate.sql.ast.tree.from.TableReferenceJoin;
@ -106,6 +107,13 @@ public class SqlTreePrinter {
}
private void logTableGroupDetails(TableGroup tableGroup) {
if (tableGroup instanceof LazyTableGroup ) {
TableGroup underlyingTableGroup = ( (LazyTableGroup) tableGroup ).getUnderlyingTableGroup();
if ( underlyingTableGroup != null ) {
logTableGroupDetails( underlyingTableGroup );
}
return;
}
logWithIndentation(
"primaryTableReference : %s as %s",
tableGroup.getPrimaryTableReference().getTableExpression(),

View File

@ -99,6 +99,7 @@ import org.hibernate.sql.ast.tree.expression.Summarization;
import org.hibernate.sql.ast.tree.expression.TrimSpecification;
import org.hibernate.sql.ast.tree.expression.UnaryOperation;
import org.hibernate.sql.ast.tree.from.FromClause;
import org.hibernate.sql.ast.tree.from.LazyTableGroup;
import org.hibernate.sql.ast.tree.from.TableGroup;
import org.hibernate.sql.ast.tree.from.TableGroupJoin;
import org.hibernate.sql.ast.tree.from.TableReference;
@ -2683,7 +2684,7 @@ public abstract class AbstractSqlAstTranslator<T extends JdbcOperation> implemen
if ( joinedGroup instanceof VirtualTableGroup ) {
processTableGroupJoins( tableGroupJoin.getJoinedGroup() );
}
else {
else if ( !( joinedGroup instanceof LazyTableGroup ) || ( (LazyTableGroup) joinedGroup ).getUnderlyingTableGroup() != null ) {
appendSql( EMPTY_STRING );
SqlAstJoinType joinType = tableGroupJoin.getJoinType();
if ( !joinedGroup.isRealTableGroup() && joinType == SqlAstJoinType.INNER && !joinedGroup.getTableReferenceJoins().isEmpty() ) {

View File

@ -9,7 +9,6 @@ package org.hibernate.sql.ast.tree.cte;
import java.util.Collections;
import java.util.List;
import java.util.function.Consumer;
import java.util.function.Supplier;
import org.hibernate.LockMode;
import org.hibernate.metamodel.mapping.ModelPart;
@ -62,7 +61,7 @@ public class CteTableGroup implements TableGroup {
}
@Override
public TableReference getTableReference(String tableExpression) {
public TableReference getTableReference(NavigablePath navigablePath, String tableExpression) {
if ( cteTableReference.getTableExpression().equals( tableExpression ) ) {
return cteTableReference;
}
@ -70,14 +69,7 @@ public class CteTableGroup implements TableGroup {
}
@Override
public TableReference resolveTableReference(String tableExpression) {
return cteTableReference;
}
@Override
public TableReference resolveTableReference(
String tableExpression,
Supplier<TableReference> creator) {
public TableReference resolveTableReference(NavigablePath navigablePath, String tableExpression) {
return cteTableReference;
}

View File

@ -7,9 +7,9 @@
package org.hibernate.sql.ast.tree.from;
import java.util.List;
import java.util.function.Supplier;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.query.NavigablePath;
/**
* @author Steve Ebersole
@ -25,20 +25,10 @@ public abstract class AbstractColumnReferenceQualifier implements ColumnReferenc
// TableReference handling
@Override
public TableReference resolveTableReference(String tableExpression, Supplier<TableReference> creator) {
final TableReference existing = getTableReferenceInternal( tableExpression );
if ( existing != null ) {
return existing;
}
return creator.get();
}
@Override
public TableReference resolveTableReference(String tableExpression) {
public TableReference resolveTableReference(NavigablePath navigablePath, String tableExpression) {
assert tableExpression != null;
final TableReference tableReference = getTableReferenceInternal( tableExpression );
final TableReference tableReference = getTableReferenceInternal( navigablePath, tableExpression );
if ( tableReference == null ) {
throw new IllegalStateException( "Could not resolve binding for table `" + tableExpression + "`" );
}
@ -47,18 +37,24 @@ public abstract class AbstractColumnReferenceQualifier implements ColumnReferenc
}
@Override
public TableReference getTableReference(String tableExpression) {
return getTableReferenceInternal( tableExpression );
public TableReference getTableReference(NavigablePath navigablePath, String tableExpression) {
return getTableReferenceInternal( navigablePath, tableExpression );
}
protected TableReference getTableReferenceInternal(String tableExpression) {
if ( getPrimaryTableReference().getTableReference( tableExpression ) != null) {
return getPrimaryTableReference();
protected TableReference getTableReferenceInternal(
NavigablePath navigablePath,
String tableExpression) {
final TableReference primaryTableReference = getPrimaryTableReference().getTableReference( navigablePath , tableExpression );
if ( primaryTableReference != null) {
return primaryTableReference;
}
for ( TableReferenceJoin tableJoin : getTableReferenceJoins() ) {
if ( tableJoin.getJoinedTableReference().getTableReference( tableExpression ) != null) {
return tableJoin.getJoinedTableReference();
final TableReference tableReference = tableJoin.getJoinedTableReference().getTableReference(
navigablePath,
tableExpression );
if ( tableReference != null) {
return tableReference;
}
}

View File

@ -6,13 +6,15 @@
*/
package org.hibernate.sql.ast.tree.from;
import java.util.function.Supplier;
import org.hibernate.query.NavigablePath;
/**
* @author Steve Ebersole
*/
public interface ColumnReferenceQualifier {
TableReference resolveTableReference(String tableExpression, Supplier<TableReference> creator);
TableReference resolveTableReference(String tableExpression);
TableReference getTableReference(String tableExpression);
TableReference resolveTableReference(NavigablePath navigablePath, String tableExpression);
TableReference getTableReference(NavigablePath navigablePath, String tableExpression);
default TableReference getTableReference(String tableExpression) {
return getTableReference( null, tableExpression );
}
}

View File

@ -10,7 +10,6 @@ import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.function.Consumer;
import java.util.function.Supplier;
import org.hibernate.LockMode;
import org.hibernate.metamodel.mapping.EmbeddableValuedModelPart;
@ -110,26 +109,19 @@ public class CompositeTableGroup implements VirtualTableGroup {
}
@Override
public TableReference getTableReference(String tableExpression) {
public TableReference getTableReference(NavigablePath navigablePath, String tableExpression) {
return underlyingTableGroup.getTableReference( tableExpression );
}
@Override
public TableReference resolveTableReference(
String tableExpression,
Supplier<TableReference> creator) {
return underlyingTableGroup.resolveTableReference( tableExpression, creator );
}
@Override
public TableReference resolveTableReference(String tableExpression) {
TableReference tableReference = underlyingTableGroup.getTableReference( tableExpression );
public TableReference resolveTableReference(NavigablePath navigablePath, String tableExpression) {
TableReference tableReference = underlyingTableGroup.getTableReference( navigablePath, tableExpression );
if ( tableReference != null ) {
return tableReference;
}
for ( TableGroupJoin tableGroupJoin : getTableGroupJoins() ) {
final TableReference primaryTableReference = tableGroupJoin.getJoinedGroup().getPrimaryTableReference();
if ( primaryTableReference.getTableExpression().equals( tableExpression ) ) {
final TableReference primaryTableReference = tableGroupJoin.getJoinedGroup().getPrimaryTableReference().getTableReference( navigablePath, tableExpression );
if ( primaryTableReference != null ) {
return primaryTableReference;
}
}

View File

@ -12,6 +12,7 @@ import java.util.function.Consumer;
import org.hibernate.LockMode;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.query.NavigablePath;
import org.hibernate.sql.ast.SqlAstJoinType;
import org.hibernate.sql.ast.spi.SqlAliasBase;
import org.hibernate.sql.ast.tree.predicate.Predicate;
@ -59,20 +60,23 @@ public class CorrelatedTableGroup extends AbstractTableGroup {
}
@Override
protected TableReference getTableReferenceInternal(String tableExpression) {
final TableReference primaryTableReference = correlatedTableGroup.getPrimaryTableReference();
if ( tableExpression.equals( primaryTableReference.getTableExpression() ) ) {
protected TableReference getTableReferenceInternal(
NavigablePath navigablePath,
String tableExpression) {
final TableReference primaryTableReference = correlatedTableGroup.getPrimaryTableReference().getTableReference( navigablePath, tableExpression );
if ( primaryTableReference != null ) {
return primaryTableReference;
}
for ( TableGroupJoin tableGroupJoin : getTableGroupJoins() ) {
final TableReference groupTableReference = tableGroupJoin.getJoinedGroup().getPrimaryTableReference();
if ( groupTableReference.getTableReference( tableExpression ) != null ) {
final TableReference groupTableReference = tableGroupJoin.getJoinedGroup().getPrimaryTableReference().getTableReference( navigablePath, tableExpression );
if ( groupTableReference != null ) {
return groupTableReference;
}
}
for ( TableReferenceJoin tableReferenceJoin : correlatedTableGroup.getTableReferenceJoins() ) {
if ( tableExpression.equals( tableReferenceJoin.getJoinedTableReference().getTableExpression() ) ) {
return tableReferenceJoin.getJoinedTableReference();
final TableReference tableReference = tableReferenceJoin.getJoinedTableReference().getTableReference( navigablePath, tableExpression );
if ( tableReference != null ) {
return tableReference;
}
}
return null;

View File

@ -0,0 +1,171 @@
/*
* 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.sql.ast.tree.from;
import java.util.Collections;
import java.util.List;
import java.util.function.Consumer;
import java.util.function.Predicate;
import java.util.function.Supplier;
import org.hibernate.LockMode;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.metamodel.mapping.ModelPart;
import org.hibernate.query.NavigablePath;
import org.hibernate.sql.ast.spi.SqlAliasBase;
/**
* @author Christian Beikov
*/
public class LazyTableGroup extends AbstractColumnReferenceQualifier implements TableGroup {
private final NavigablePath navigablePath;
private final TableGroupProducer producer;
private final LockMode lockMode;
private final SqlAliasBase sqlAliasBase;
private final SessionFactoryImplementor sessionFactory;
private final Supplier<TableGroup> tableGroupSupplier;
private final TableGroup parentTableGroup;
private final Predicate<NavigablePath> navigablePathChecker;
private Consumer<TableGroup> tableGroupConsumer;
private TableGroup tableGroup;
public LazyTableGroup(
NavigablePath navigablePath,
Supplier<TableGroup> tableGroupSupplier,
Predicate<NavigablePath> navigablePathChecker,
TableGroupProducer tableGroupProducer,
LockMode lockMode,
SqlAliasBase sqlAliasBase,
SessionFactoryImplementor sessionFactory,
TableGroup parentTableGroup) {
this.navigablePath = navigablePath;
this.producer = tableGroupProducer;
this.lockMode = lockMode;
this.sqlAliasBase = sqlAliasBase;
this.tableGroupSupplier = tableGroupSupplier;
this.navigablePathChecker = navigablePathChecker;
this.parentTableGroup = parentTableGroup;
this.sessionFactory = sessionFactory;
}
public TableGroup getUnderlyingTableGroup() {
return tableGroup;
}
private TableGroup getTableGroup() {
if ( tableGroup != null ) {
return tableGroup;
}
tableGroup = tableGroupSupplier.get();
if ( tableGroupConsumer != null ) {
tableGroupConsumer.accept( tableGroup );
}
return tableGroup;
}
public void setTableGroupInitializerCallback(Consumer<TableGroup> tableGroupConsumer) {
this.tableGroupConsumer = tableGroupConsumer;
}
@Override
public void applyAffectedTableNames(Consumer<String> nameCollector) {
if ( tableGroup != null ) {
tableGroup.applyAffectedTableNames( nameCollector );
}
}
@Override
public TableReference getPrimaryTableReference() {
return getTableGroup().getPrimaryTableReference();
}
@Override
public List<TableReferenceJoin> getTableReferenceJoins() {
return tableGroup == null ? Collections.emptyList() : tableGroup.getTableReferenceJoins();
}
@Override
public List<TableGroupJoin> getTableGroupJoins() {
return tableGroup == null ? Collections.emptyList() : tableGroup.getTableGroupJoins();
}
@Override
public boolean hasTableGroupJoins() {
return tableGroup != null && tableGroup.hasTableGroupJoins();
}
@Override
public void addTableGroupJoin(TableGroupJoin join) {
getTableGroup().addTableGroupJoin( join );
}
@Override
public void visitTableGroupJoins(Consumer<TableGroupJoin> consumer) {
if ( tableGroup != null ) {
tableGroup.visitTableGroupJoins( consumer );
}
}
@Override
public NavigablePath getNavigablePath() {
return navigablePath;
}
@Override
public String getGroupAlias() {
return sqlAliasBase.getAliasStem();
}
@Override
public TableGroupProducer getModelPart() {
return producer;
}
@Override
public ModelPart getExpressionType() {
return getModelPart();
}
@Override
public LockMode getLockMode() {
return lockMode;
}
@Override
protected SessionFactoryImplementor getSessionFactory() {
return sessionFactory;
}
@Override
public boolean isInnerJoinPossible() {
return false;
}
@Override
public boolean isRealTableGroup() {
return false;
}
@Override
public TableReference getTableReferenceInternal(
NavigablePath navigablePath,
String tableExpression) {
if ( navigablePath == null || navigablePathChecker.test( navigablePath ) ) {
final TableReference reference = parentTableGroup.getTableReference(
navigablePath,
tableExpression
);
if ( reference != null ) {
return reference;
}
}
return getTableGroup().getTableReference( navigablePath, tableExpression );
}
}

View File

@ -9,7 +9,6 @@ package org.hibernate.sql.ast.tree.from;
import java.util.Collections;
import java.util.List;
import java.util.function.Consumer;
import java.util.function.Supplier;
import org.hibernate.LockMode;
import org.hibernate.metamodel.mapping.ModelPart;
@ -62,20 +61,15 @@ public class MutatingTableReferenceGroupWrapper implements VirtualTableGroup {
}
@Override
public TableReference getTableReference(String tableExpression) {
public TableReference getTableReference(NavigablePath navigablePath, String tableExpression) {
return mutatingTableReference.getTableExpression().equals( tableExpression )
? mutatingTableReference
: null;
}
@Override
public TableReference resolveTableReference(String tableExpression, Supplier<TableReference> creator) {
return resolveTableReference( tableExpression );
}
@Override
public TableReference resolveTableReference(String tableExpression) {
return getTableReference( tableExpression );
public TableReference resolveTableReference(NavigablePath navigablePath, String tableExpression) {
return getTableReference( navigablePath, tableExpression );
}
@Override

View File

@ -26,6 +26,7 @@ public class StandardTableGroup extends AbstractTableGroup {
private final Predicate<String> tableReferenceJoinNameChecker;
private final BiFunction<String,TableGroup,TableReferenceJoin> tableReferenceJoinCreator;
private final boolean realTableGroup;
private final boolean fetched;
private List<TableReferenceJoin> tableJoins;
@ -39,6 +40,7 @@ public class StandardTableGroup extends AbstractTableGroup {
super( navigablePath, tableGroupProducer, lockMode, sqlAliasBase, sessionFactory );
this.primaryTableReference = primaryTableReference;
this.realTableGroup = false;
this.fetched = false;
this.tableJoins = Collections.emptyList();
this.tableReferenceJoinCreator = null;
this.tableReferenceJoinNameChecker = s -> {
@ -64,6 +66,27 @@ public class StandardTableGroup extends AbstractTableGroup {
super( navigablePath, tableGroupProducer, lockMode, sqlAliasBase, sessionFactory );
this.primaryTableReference = primaryTableReference;
this.realTableGroup = realTableGroup;
this.fetched = false;
this.tableJoins = null;
this.tableReferenceJoinNameChecker = tableReferenceJoinNameChecker;
this.tableReferenceJoinCreator = tableReferenceJoinCreator;
}
public StandardTableGroup(
NavigablePath navigablePath,
TableGroupProducer tableGroupProducer,
boolean fetched,
LockMode lockMode,
TableReference primaryTableReference,
boolean realTableGroup,
SqlAliasBase sqlAliasBase,
Predicate<String> tableReferenceJoinNameChecker,
BiFunction<String, TableGroup, TableReferenceJoin> tableReferenceJoinCreator,
SessionFactoryImplementor sessionFactory) {
super( navigablePath, tableGroupProducer, lockMode, sqlAliasBase, sessionFactory );
this.primaryTableReference = primaryTableReference;
this.realTableGroup = realTableGroup;
this.fetched = fetched;
this.tableJoins = null;
this.tableReferenceJoinNameChecker = tableReferenceJoinNameChecker;
this.tableReferenceJoinCreator = tableReferenceJoinCreator;
@ -78,11 +101,6 @@ public class StandardTableGroup extends AbstractTableGroup {
}
}
@Override
public TableReference getTableReference(String tableExpression) {
return getTableReferenceInternal( tableExpression );
}
@Override
public TableReference getPrimaryTableReference() {
return primaryTableReference;
@ -98,6 +116,11 @@ public class StandardTableGroup extends AbstractTableGroup {
return realTableGroup;
}
@Override
public boolean isFetched() {
return fetched;
}
public void addTableReferenceJoin(TableReferenceJoin join) {
if ( tableJoins == null ) {
tableJoins = new ArrayList<>();
@ -106,8 +129,10 @@ public class StandardTableGroup extends AbstractTableGroup {
}
@Override
public TableReference getTableReferenceInternal(String tableExpression) {
TableReference tableReference = primaryTableReference.getTableReference( tableExpression );
public TableReference getTableReferenceInternal(
NavigablePath navigablePath,
String tableExpression) {
TableReference tableReference = primaryTableReference.getTableReference( navigablePath, tableExpression );
if ( tableReference != null ) {
return tableReference;
}
@ -118,7 +143,7 @@ public class StandardTableGroup extends AbstractTableGroup {
final TableReferenceJoin join = tableJoins.get( i );
assert join != null;
final TableReference resolveTableReference = join.getJoinedTableReference()
.getTableReference( tableExpression );
.getTableReference( navigablePath, tableExpression );
if ( resolveTableReference != null ) {
return resolveTableReference;
}
@ -130,7 +155,7 @@ public class StandardTableGroup extends AbstractTableGroup {
for ( TableGroupJoin tableGroupJoin : getTableGroupJoins() ) {
final TableReference primaryTableReference = tableGroupJoin.getJoinedGroup().getPrimaryTableReference();
if ( primaryTableReference.getTableReference( tableExpression ) != null ) {
if ( primaryTableReference.getTableReference( navigablePath, tableExpression ) != null ) {
return primaryTableReference;
}
}

View File

@ -91,4 +91,8 @@ public interface TableGroup extends SqlAstNode, ColumnReferenceQualifier, SqmPat
default boolean isRealTableGroup() {
return false;
}
default boolean isFetched() {
return false;
}
}

View File

@ -26,6 +26,7 @@ public interface TableGroupJoinProducer extends TableGroupProducer {
TableGroup lhs,
String explicitSourceAlias,
SqlAstJoinType sqlAstJoinType,
boolean fetched,
LockMode lockMode,
SqlAstCreationState creationState) {
return createTableGroupJoin(
@ -33,6 +34,7 @@ public interface TableGroupJoinProducer extends TableGroupProducer {
lhs,
explicitSourceAlias,
sqlAstJoinType,
fetched,
lockMode,
creationState.getSqlAliasBaseGenerator(),
creationState.getSqlExpressionResolver(),
@ -48,6 +50,7 @@ public interface TableGroupJoinProducer extends TableGroupProducer {
TableGroup lhs,
String explicitSourceAlias,
SqlAstJoinType sqlAstJoinType,
boolean fetched,
LockMode lockMode,
SqlAliasBaseGenerator aliasBaseGenerator,
SqlExpressionResolver sqlExpressionResolver,

View File

@ -7,9 +7,9 @@
package org.hibernate.sql.ast.tree.from;
import java.util.Objects;
import java.util.function.Supplier;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.query.NavigablePath;
import org.hibernate.sql.ast.SqlAstWalker;
import org.hibernate.sql.ast.tree.SqlAstNode;
@ -52,12 +52,7 @@ public class TableReference implements SqlAstNode, ColumnReferenceQualifier {
}
@Override
public TableReference resolveTableReference(String tableExpression, Supplier<TableReference> creator) {
throw new UnsupportedOperationException( "Cannot create a TableReference relative to a TableReference" );
}
@Override
public TableReference resolveTableReference(String tableExpression) {
public TableReference resolveTableReference(NavigablePath navigablePath, String tableExpression) {
if ( tableExpression.equals( getTableExpression() ) ) {
return this;
}
@ -65,7 +60,7 @@ public class TableReference implements SqlAstNode, ColumnReferenceQualifier {
}
@Override
public TableReference getTableReference(String tableExpression) {
public TableReference getTableReference(NavigablePath navigablePath, String tableExpression) {
if ( this.tableExpression.equals( tableExpression ) ) {
return this;
}

View File

@ -10,7 +10,6 @@ import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.function.Consumer;
import java.util.function.Supplier;
import org.hibernate.LockMode;
import org.hibernate.metamodel.mapping.ModelPart;
@ -109,19 +108,13 @@ public class UnionTableGroup implements VirtualTableGroup {
}
@Override
public TableReference getTableReference(String tableExpression) {
public TableReference getTableReference(NavigablePath navigablePath, String tableExpression) {
// assert tableReference.getTableExpression().equals( tableExpression );
return tableReference;
}
@Override
public TableReference resolveTableReference(String tableExpression, Supplier<TableReference> creator) {
assert tableReference.getTableExpression().equals( tableExpression );
return tableReference;
}
@Override
public TableReference resolveTableReference(String tableExpression) {
public TableReference resolveTableReference(NavigablePath navigablePath, String tableExpression) {
// assert tableReference.getTableExpression().equals( tableExpression );
return tableReference;
}

View File

@ -7,6 +7,7 @@
package org.hibernate.sql.ast.tree.from;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.query.NavigablePath;
/**
* @author Andrea Boriero
@ -25,7 +26,7 @@ public class UnionTableReference extends TableReference {
this.subclassTableSpaceExpressions = subclassTableSpaceExpressions;
}
public TableReference resolveTableReference(String tableExpression) {
public TableReference resolveTableReference(NavigablePath navigablePath, String tableExpression) {
if ( hasTableExpression( tableExpression ) ) {
return this;
}
@ -33,7 +34,7 @@ public class UnionTableReference extends TableReference {
}
@Override
public TableReference getTableReference(String tableExpression) {
public TableReference getTableReference(NavigablePath navigablePath, String tableExpression) {
if ( hasTableExpression( tableExpression ) ) {
return this;
}

View File

@ -42,6 +42,10 @@ public interface FetchParent extends DomainResultGraphNode {
return null;
}
default NavigablePath resolveNavigablePath(Fetchable fetchable) {
return getNavigablePath().append( fetchable.getFetchableName() );
}
/**
* Whereas {@link #getReferencedMappingContainer} and {@link #getReferencedMappingType} return the
* referenced container type, this method returns the referenced part.

View File

@ -8,7 +8,6 @@ package org.hibernate.sql.results.graph.collection.internal;
import java.util.List;
import java.util.function.Consumer;
import java.util.function.Supplier;
import org.hibernate.LockMode;
import org.hibernate.metamodel.mapping.ModelPart;
@ -103,18 +102,13 @@ public class EntityCollectionPartTableGroup implements TableGroup {
}
@Override
public TableReference getTableReference(String tableExpression) {
public TableReference getTableReference(NavigablePath navigablePath, String tableExpression) {
return collectionTableGroup.getTableReference( tableExpression );
}
@Override
public TableReference resolveTableReference(String tableExpression, Supplier<TableReference> creator) {
return collectionTableGroup.resolveTableReference( tableExpression, creator );
}
@Override
public TableReference resolveTableReference(String tableExpression) {
return collectionTableGroup.resolveTableReference( tableExpression );
public TableReference resolveTableReference(NavigablePath navigablePath, String tableExpression) {
return collectionTableGroup.resolveTableReference( navigablePath, tableExpression );
}
@Override

View File

@ -66,6 +66,7 @@ public class EmbeddableFetchImpl extends AbstractFetchParent implements Embeddab
lhsTableGroup,
null,
nullable ? SqlAstJoinType.LEFT : SqlAstJoinType.INNER,
true,
LockMode.NONE,
creationState.getSqlAstCreationState()
);

View File

@ -61,12 +61,22 @@ public class EmbeddableForeignKeyResultImpl<T>
LockMode lockMode,
String resultVariable,
DomainResultCreationState creationState) {
final boolean shouldSelect;
if ( fetchable instanceof ToOneAttributeMapping ) {
// We need to make sure to-ones are always delayed to avoid cycles while resolving entity keys
final ToOneAttributeMapping toOne = (ToOneAttributeMapping) fetchable;
shouldSelect = selected && !creationState.isAssociationKeyVisited(
toOne.getForeignKeyDescriptor().getAssociationKey()
);
}
else {
shouldSelect = selected;
}
return fetchable.generateFetch(
this,
fetchablePath,
fetchTiming,
// We need to make sure to-ones are always delayed to avoid cycles while resolving entity keys
selected && !( fetchable instanceof ToOneAttributeMapping ),
shouldSelect,
lockMode,
resultVariable,
creationState

View File

@ -52,6 +52,7 @@ public class EmbeddableResultImpl<T> extends AbstractFetchParent implements Embe
fromClauseAccess.findTableGroup( navigablePath.getParent() ),
resultVariable,
SqlAstJoinType.INNER,
true,
LockMode.NONE,
creationState.getSqlAstCreationState()
);

View File

@ -73,6 +73,16 @@ public abstract class AbstractEntityResultGraphNode extends AbstractFetchParent
identifierResult = null;
visitIdentifierMapping( identifierNavigablePath, creationState, identifierMapping, entityTableGroup );
}
else if ( referencedModelPart instanceof ToOneAttributeMapping
&& ( (ToOneAttributeMapping) referencedModelPart ).canJoinForeignKey( identifierMapping ) ) {
// If we don't do this here, LazyTableGroup#getTableReferenceInternal would have to use the target table in case {id} is encountered
identifierResult = ( (ToOneAttributeMapping) referencedModelPart ).getForeignKeyDescriptor().createDomainResult(
navigablePath,
creationState.getSqlAstCreationState().getFromClauseAccess().findTableGroup( navigablePath.getParent() ),
null,
creationState
);
}
else {
identifierResult = identifierMapping.createDomainResult(
identifierNavigablePath,

View File

@ -9,6 +9,7 @@ package org.hibernate.sql.results.graph.entity.internal;
import org.hibernate.LockMode;
import org.hibernate.engine.FetchTiming;
import org.hibernate.query.NavigablePath;
import org.hibernate.sql.ast.tree.from.TableGroup;
import org.hibernate.sql.results.graph.AssemblerCreationState;
import org.hibernate.sql.results.graph.DomainResultCreationState;
import org.hibernate.sql.results.graph.FetchParent;
@ -29,6 +30,7 @@ public class EntityFetchJoinedImpl extends AbstractNonLazyEntityFetch {
public EntityFetchJoinedImpl(
FetchParent fetchParent,
EntityValuedFetchable fetchedAttribute,
TableGroup tableGroup,
LockMode lockMode,
boolean nullable,
NavigablePath navigablePath,
@ -38,6 +40,7 @@ public class EntityFetchJoinedImpl extends AbstractNonLazyEntityFetch {
entityResult = new EntityResultImpl(
navigablePath,
fetchedAttribute,
tableGroup,
null,
creationState
);

View File

@ -9,9 +9,13 @@ package org.hibernate.sql.results.graph.entity.internal;
import org.hibernate.metamodel.mapping.EntityMappingType;
import org.hibernate.metamodel.mapping.EntityValuedModelPart;
import org.hibernate.query.NavigablePath;
import org.hibernate.sql.ast.tree.from.TableGroup;
import org.hibernate.sql.ast.tree.from.TableGroupJoin;
import org.hibernate.sql.ast.tree.from.TableGroupProducer;
import org.hibernate.sql.results.graph.AssemblerCreationState;
import org.hibernate.sql.results.graph.DomainResultAssembler;
import org.hibernate.sql.results.graph.DomainResultCreationState;
import org.hibernate.sql.results.graph.Fetchable;
import org.hibernate.sql.results.graph.FetchableContainer;
import org.hibernate.sql.results.graph.entity.AbstractEntityResultGraphNode;
import org.hibernate.sql.results.graph.entity.EntityInitializer;
@ -24,19 +28,22 @@ import org.hibernate.sql.results.graph.entity.EntityResult;
*/
public class EntityResultImpl extends AbstractEntityResultGraphNode implements EntityResult {
private final TableGroup tableGroup;
private final String resultVariable;
public EntityResultImpl(
NavigablePath navigablePath,
EntityValuedModelPart entityValuedModelPart,
TableGroup tableGroup,
String resultVariable,
DomainResultCreationState creationState) {
this( navigablePath, entityValuedModelPart, resultVariable, null, creationState );
this( navigablePath, entityValuedModelPart, tableGroup, resultVariable, null, creationState );
}
public EntityResultImpl(
NavigablePath navigablePath,
EntityValuedModelPart entityValuedModelPart,
TableGroup tableGroup,
String resultVariable,
EntityMappingType targetType,
DomainResultCreationState creationState) {
@ -46,12 +53,27 @@ public class EntityResultImpl extends AbstractEntityResultGraphNode implements E
navigablePath,
creationState
);
this.tableGroup = tableGroup;
this.resultVariable = resultVariable;
afterInitialize( creationState );
}
@Override
public NavigablePath resolveNavigablePath(Fetchable fetchable) {
// todo: this is not ideal yet as we could potentially resolve a path that we did not intend
// to fix this, we'd need to know if the table group is for a fetch
if ( fetchable instanceof TableGroupProducer &&
!getNavigablePath().getUnaliasedLocalName().equals( getNavigablePath().getLocalName() ) ) {
for ( TableGroupJoin tableGroupJoin : tableGroup.getTableGroupJoins() ) {
if ( tableGroupJoin.getJoinedGroup().isFetched() && tableGroupJoin.getJoinedGroup().getModelPart() == fetchable ) {
return tableGroupJoin.getNavigablePath();
}
}
}
return super.resolveNavigablePath( fetchable );
}
@Override
public FetchableContainer getReferencedMappingType() {
return getReferencedMappingContainer();

View File

@ -24,9 +24,10 @@ public class EntityResultJoinedSubclassImpl extends EntityResultImpl {
public EntityResultJoinedSubclassImpl(
NavigablePath navigablePath,
EntityValuedModelPart entityValuedModelPart,
TableGroup tableGroup,
String resultVariable,
DomainResultCreationState creationState) {
super( navigablePath, entityValuedModelPart, resultVariable, creationState );
super( navigablePath, entityValuedModelPart, tableGroup, resultVariable, creationState );
}
@Override

View File

@ -29,6 +29,7 @@ import org.hibernate.type.descriptor.jdbc.RealTypeDescriptor;
import org.hibernate.type.descriptor.jdbc.SmallIntTypeDescriptor;
import org.hibernate.type.descriptor.jdbc.TimeTypeDescriptor;
import org.hibernate.type.descriptor.jdbc.TimestampTypeDescriptor;
import org.hibernate.type.descriptor.jdbc.TimestampWithTimeZoneDescriptor;
import org.hibernate.type.descriptor.jdbc.TinyIntTypeDescriptor;
import org.hibernate.type.descriptor.jdbc.VarbinaryTypeDescriptor;
import org.hibernate.type.descriptor.jdbc.VarcharTypeDescriptor;
@ -57,6 +58,7 @@ public class JdbcTypeDescriptorBaseline {
target.addDescriptor( DateTypeDescriptor.INSTANCE );
target.addDescriptor( TimestampTypeDescriptor.INSTANCE );
target.addDescriptor( TimestampWithTimeZoneDescriptor.INSTANCE );
target.addDescriptor( TimeTypeDescriptor.INSTANCE );
target.addDescriptor( BinaryTypeDescriptor.INSTANCE );

Some files were not shown because too many files have changed in this diff Show More