Capture whether a foreign key is constrained and allow skipping the foreign key access optimization explicitly

This commit is contained in:
Christian Beikov 2021-09-01 18:08:51 +02:00
parent f23ecfc58e
commit 86000e9f22
22 changed files with 228 additions and 113 deletions

View File

@ -469,6 +469,10 @@ public abstract class SimpleValue implements KeyValue {
public void setForeignKeyName(String foreignKeyName) {
this.foreignKeyName = foreignKeyName;
}
public boolean isConstrained() {
return !"none".equals( foreignKeyName ) && !hasFormula();
}
public String getForeignKeyDefinition() {
return foreignKeyDefinition;

View File

@ -135,4 +135,6 @@ public interface ForeignKeyDescriptor extends VirtualModelPart {
MappingModelCreationProcess creationProcess);
AssociationKey getAssociationKey();
boolean hasConstraint();
}

View File

@ -212,7 +212,7 @@ public class BasicAttributeMapping
TableGroup tableGroup,
String resultVariable,
DomainResultCreationState creationState) {
final SqlSelection sqlSelection = resolveSqlSelection( tableGroup, creationState );
final SqlSelection sqlSelection = resolveSqlSelection( tableGroup, true, creationState );
//noinspection unchecked
return new BasicResult(
@ -224,12 +224,15 @@ public class BasicAttributeMapping
);
}
private SqlSelection resolveSqlSelection(TableGroup tableGroup, DomainResultCreationState creationState) {
private SqlSelection resolveSqlSelection(
TableGroup tableGroup,
boolean allowFkOptimization,
DomainResultCreationState creationState) {
final SqlExpressionResolver expressionResolver = creationState.getSqlAstCreationState().getSqlExpressionResolver();
final TableReference tableReference = tableGroup.resolveTableReference(
tableGroup.getNavigablePath()
.append( getNavigableRole().getNavigableName() ),
getContainingTableExpression()
tableGroup.getNavigablePath().append( getNavigableRole().getNavigableName() ),
getContainingTableExpression(),
allowFkOptimization
);
final String tableAlias = tableReference.getIdentificationVariable();
return expressionResolver.resolveSqlSelection(
@ -254,7 +257,7 @@ public class BasicAttributeMapping
NavigablePath navigablePath,
TableGroup tableGroup,
DomainResultCreationState creationState) {
resolveSqlSelection( tableGroup, creationState );
resolveSqlSelection( tableGroup, true, creationState );
}
@Override
@ -263,7 +266,7 @@ public class BasicAttributeMapping
TableGroup tableGroup,
DomainResultCreationState creationState,
BiConsumer<SqlSelection, JdbcMapping> selectionConsumer) {
selectionConsumer.accept( resolveSqlSelection( tableGroup, creationState ), getJdbcMapping() );
selectionConsumer.accept( resolveSqlSelection( tableGroup, true, creationState ), getJdbcMapping() );
}
@Override
@ -291,7 +294,7 @@ public class BasicAttributeMapping
assert tableGroup != null;
final SqlSelection sqlSelection = resolveSqlSelection( tableGroup, creationState );
final SqlSelection sqlSelection = resolveSqlSelection( tableGroup, false, creationState );
valuesArrayPosition = sqlSelection.getValuesArrayPosition();
}

View File

@ -175,7 +175,7 @@ public class BasicEntityIdentifierMappingImpl implements BasicEntityIdentifierMa
TableGroup tableGroup,
String resultVariable,
DomainResultCreationState creationState) {
final SqlSelection sqlSelection = resolveSqlSelection( navigablePath, tableGroup, creationState );
final SqlSelection sqlSelection = resolveSqlSelection( navigablePath, tableGroup, true, creationState );
return new BasicResult(
sqlSelection.getValuesArrayPosition(),
@ -190,18 +190,19 @@ public class BasicEntityIdentifierMappingImpl implements BasicEntityIdentifierMa
NavigablePath navigablePath,
TableGroup tableGroup,
DomainResultCreationState creationState) {
resolveSqlSelection( navigablePath, tableGroup, creationState );
resolveSqlSelection( navigablePath, tableGroup, true, creationState );
}
private SqlSelection resolveSqlSelection(
NavigablePath navigablePath,
TableGroup tableGroup,
boolean allowFkOptimization,
DomainResultCreationState creationState) {
final SqlExpressionResolver expressionResolver = creationState.getSqlAstCreationState()
.getSqlExpressionResolver();
final TableReference rootTableReference;
try {
rootTableReference = tableGroup.resolveTableReference( navigablePath, rootTable );
rootTableReference = tableGroup.resolveTableReference( navigablePath, rootTable, allowFkOptimization );
}
catch (Exception e) {
throw new IllegalStateException(

View File

@ -58,6 +58,7 @@ public class EmbeddedForeignKeyDescriptor implements ForeignKeyDescriptor {
private final String targetTable;
private final SelectableMappings targetSelectableMappings;
private final AssociationKey associationKey;
private final boolean hasConstraint;
public EmbeddedForeignKeyDescriptor(
EmbeddableValuedModelPart keyMappingType,
@ -66,6 +67,7 @@ public class EmbeddedForeignKeyDescriptor implements ForeignKeyDescriptor {
SelectableMappings keySelectableMappings,
String targetTable,
SelectableMappings targetSelectableMappings,
boolean hasConstraint,
MappingModelCreationProcess creationProcess) {
this.keyTable = keyTable;
this.keySelectableMappings = keySelectableMappings;
@ -80,6 +82,7 @@ public class EmbeddedForeignKeyDescriptor implements ForeignKeyDescriptor {
}
);
this.associationKey = new AssociationKey( keyTable, columns );
this.hasConstraint = hasConstraint;
creationProcess.registerInitializationCallback(
"Embedded (composite) FK descriptor " + targetMappingType.getNavigableRole(),
@ -121,6 +124,7 @@ public class EmbeddedForeignKeyDescriptor implements ForeignKeyDescriptor {
}
);
this.associationKey = new AssociationKey( keyTable, columns );
this.hasConstraint = original.hasConstraint;
}
@Override
@ -439,8 +443,7 @@ public class EmbeddedForeignKeyDescriptor implements ForeignKeyDescriptor {
}
final TableReference tableReference = lhs.resolveTableReference(
lhs.getNavigablePath()
.append( getNavigableRole().getNavigableName() ),
lhs.getNavigablePath().append( getNavigableRole().getNavigableName() ),
table
);
if ( tableReference != null ) {
@ -460,6 +463,11 @@ public class EmbeddedForeignKeyDescriptor implements ForeignKeyDescriptor {
return targetSelectableMappings.forEachSelectable( offset, consumer );
}
@Override
public boolean hasConstraint() {
return hasConstraint;
}
@Override
public AssociationKey getAssociationKey() {
return associationKey;

View File

@ -45,6 +45,7 @@ import org.hibernate.mapping.PersistentClass;
import org.hibernate.mapping.Property;
import org.hibernate.mapping.Resolvable;
import org.hibernate.mapping.Selectable;
import org.hibernate.mapping.SimpleValue;
import org.hibernate.mapping.Table;
import org.hibernate.mapping.ToOne;
import org.hibernate.mapping.Value;
@ -932,7 +933,8 @@ public class MappingModelCreationHelper {
null,
keySelectableMapping,
simpleFkTarget,
isReferenceToPrimaryKey
isReferenceToPrimaryKey,
( (SimpleValue) bootValueMappingKey ).isConstrained()
)
);
}
@ -1077,6 +1079,7 @@ public class MappingModelCreationHelper {
keySelectableMapping,
simpleFkTarget,
bootValueMapping.isReferenceToPrimaryKey(),
bootValueMapping.isConstrained(),
swapDirection
);
attributeMapping.setForeignKeyDescriptor( foreignKeyDescriptor );
@ -1119,10 +1122,12 @@ public class MappingModelCreationHelper {
boolean inverse,
Dialect dialect,
MappingModelCreationProcess creationProcess) {
final boolean hasConstraint;
final SelectableMappings keySelectableMappings;
final String keyTableExpression;
if ( bootValueMapping instanceof Collection ) {
final Collection collectionBootValueMapping = (Collection) bootValueMapping;
hasConstraint = ( (SimpleValue) collectionBootValueMapping.getKey() ).isConstrained();
keyTableExpression = getTableIdentifierExpression(
collectionBootValueMapping.getCollectionTable(),
creationProcess
@ -1137,6 +1142,13 @@ public class MappingModelCreationHelper {
);
}
else {
if ( bootValueMapping instanceof OneToMany ) {
// We assume there is a constraint if the mapping is not nullable
hasConstraint = !bootValueMapping.isNullable();
}
else {
hasConstraint = ( (SimpleValue) bootValueMapping ).isConstrained();
}
keyTableExpression = getTableIdentifierExpression(
bootValueMapping.getTable(),
creationProcess
@ -1162,6 +1174,7 @@ public class MappingModelCreationHelper {
embeddableValuedModelPart.getEmbeddableTypeDescriptor(),
keyTableExpression,
keySelectableMappings,
hasConstraint,
creationProcess
);
}
@ -1177,6 +1190,7 @@ public class MappingModelCreationHelper {
keySelectableMappings,
embeddableValuedModelPart.getContainingTableExpression(),
embeddableValuedModelPart.getEmbeddableTypeDescriptor(),
hasConstraint,
creationProcess
);
}

View File

@ -25,6 +25,7 @@ import org.hibernate.mapping.IndexedCollection;
import org.hibernate.mapping.IndexedConsumer;
import org.hibernate.mapping.List;
import org.hibernate.mapping.Property;
import org.hibernate.mapping.SimpleValue;
import org.hibernate.mapping.Value;
import org.hibernate.metamodel.mapping.BasicValuedModelPart;
import org.hibernate.metamodel.mapping.CollectionIdentifierDescriptor;
@ -338,12 +339,21 @@ public class PluralAttributeMappingImpl
dialect,
creationProcess.getSqmFunctionRegistry()
);
final boolean hasConstraint;
if ( fkBootDescriptorSource instanceof SimpleValue ) {
hasConstraint = ( (SimpleValue) fkBootDescriptorSource ).isConstrained();
}
else {
// We assume there is a constraint if the key is not nullable
hasConstraint = !fkBootDescriptorSource.isNullable();
}
return new SimpleForeignKeyDescriptor(
basicFkTargetPart,
null,
keySelectableMapping,
basicFkTargetPart,
entityType.isReferenceToPrimaryKey()
entityType.isReferenceToPrimaryKey(),
hasConstraint
);
}
else if ( fkTargetPart instanceof EmbeddableValuedModelPart ) {

View File

@ -57,7 +57,7 @@ public class SimpleForeignKeyDescriptor implements ForeignKeyDescriptor, BasicVa
private final SimpleForeignKeyDescriptorSide targetSide;
private final boolean refersToPrimaryKey;
private final boolean hasConstraint;
private AssociationKey associationKey;
public SimpleForeignKeyDescriptor(
@ -65,8 +65,9 @@ public class SimpleForeignKeyDescriptor implements ForeignKeyDescriptor, BasicVa
PropertyAccess keyPropertyAccess,
SelectableMapping keySelectableMapping,
BasicValuedModelPart targetModelPart,
boolean refersToPrimaryKey) {
this( keyModelPart, keyPropertyAccess, keySelectableMapping, targetModelPart, refersToPrimaryKey, false );
boolean refersToPrimaryKey,
boolean hasConstraint) {
this( keyModelPart, keyPropertyAccess, keySelectableMapping, targetModelPart, refersToPrimaryKey, hasConstraint, false );
}
public SimpleForeignKeyDescriptor(
@ -75,6 +76,7 @@ public class SimpleForeignKeyDescriptor implements ForeignKeyDescriptor, BasicVa
SelectableMapping keySelectableMapping,
BasicValuedModelPart targetModelPart,
boolean refersToPrimaryKey,
boolean hasConstraint,
boolean swapDirection) {
assert keySelectableMapping != null;
assert targetModelPart != null;
@ -94,6 +96,7 @@ public class SimpleForeignKeyDescriptor implements ForeignKeyDescriptor, BasicVa
this.targetSide = new SimpleForeignKeyDescriptorSide( Nature.TARGET, targetModelPart );
}
this.refersToPrimaryKey = refersToPrimaryKey;
this.hasConstraint = hasConstraint;
}
@Override
@ -135,7 +138,8 @@ public class SimpleForeignKeyDescriptor implements ForeignKeyDescriptor, BasicVa
( (PropertyBasedMapping) keySide.getModelPart() ).getPropertyAccess(),
selectableMappingAccess.apply( 0 ),
targetSide.getModelPart(),
refersToPrimaryKey
refersToPrimaryKey,
hasConstraint
);
}
@ -426,6 +430,11 @@ public class SimpleForeignKeyDescriptor implements ForeignKeyDescriptor, BasicVa
return getJdbcTypeCount();
}
@Override
public boolean hasConstraint() {
return hasConstraint;
}
@Override
public AssociationKey getAssociationKey() {
if ( associationKey == null ) {

View File

@ -345,28 +345,9 @@ public class ToOneAttributeMapping
? ForeignKeyDescriptor.Nature.KEY
: ForeignKeyDescriptor.Nature.TARGET;
// Determine if the FK maps the id of the owner entity
final boolean[] mapsId = new boolean[1];
final EntityMappingType containingEntityMapping = findContainingEntityMapping();
foreignKeyDescriptor.getKeyPart().forEachSelectable(
(fkIndex, fkMapping) -> {
if ( !mapsId[0] ) {
containingEntityMapping.getEntityPersister().getIdentifierMapping().forEachSelectable(
(idIndex, idMapping) -> {
if ( fkMapping.getContainingTableExpression()
.equals( idMapping.getContainingTableExpression() )
&& fkMapping.getSelectionExpression()
.equals( idMapping.getSelectionExpression() ) ) {
mapsId[0] = true;
}
}
);
}
}
);
// We can only use the parent table group if the FK is located there
// If this is not the case, the FK is on a join/secondary table, so we need a join
this.canUseParentTableGroup = !mapsId[0] && sideNature == ForeignKeyDescriptor.Nature.KEY
// We can only use the parent table group if the FK is located there and ignoreNotFound is false
// If this is not the case, the FK is not constrained or on a join/secondary table, so we need a join
this.canUseParentTableGroup = !isIgnoreNotFound && sideNature == ForeignKeyDescriptor.Nature.KEY
&& declaringTableGroupProducer.containsTableReference( identifyingColumnsTableExpression );
}
@ -881,7 +862,7 @@ public class ToOneAttributeMapping
SqlExpressionResolver sqlExpressionResolver,
SqlAstCreationContext creationContext) {
final SqlAliasBase sqlAliasBase = aliasBaseGenerator.createSqlAliasBase( sqlAliasStem );
boolean canUseInnerJoin = sqlAstJoinType == SqlAstJoinType.INNER || lhs.canUseInnerJoins() && !isNullable;
final boolean canUseInnerJoin = sqlAstJoinType == SqlAstJoinType.INNER || lhs.canUseInnerJoins() && !isNullable;
final LazyTableGroup lazyTableGroup = new LazyTableGroup(
canUseInnerJoin,
navigablePath,

View File

@ -119,8 +119,11 @@ public class TableGroupImpl implements TableGroup {
}
@Override
public TableReference resolveTableReference(NavigablePath navigablePath, String tableExpression) {
final TableReference tableReference = getTableReference( navigablePath, tableExpression );
public TableReference resolveTableReference(
NavigablePath navigablePath,
String tableExpression,
boolean allowFkOptimization) {
final TableReference tableReference = getTableReference( navigablePath, tableExpression, allowFkOptimization );
if ( tableReference == null ) {
throw new IllegalStateException( "Could not resolve binding for table `" + tableExpression + "`" );
}
@ -129,14 +132,17 @@ public class TableGroupImpl implements TableGroup {
}
@Override
public TableReference getTableReference(NavigablePath navigablePath, String tableExpression) {
if ( primaryTableReference.getTableReference( navigablePath , tableExpression ) != null ) {
public TableReference getTableReference(
NavigablePath navigablePath,
String tableExpression,
boolean allowFkOptimization) {
if ( primaryTableReference.getTableReference( navigablePath , tableExpression, allowFkOptimization ) != null ) {
return primaryTableReference;
}
for ( TableGroupJoin tableGroupJoin : getTableGroupJoins() ) {
final TableReference primaryTableReference = tableGroupJoin.getJoinedGroup().getPrimaryTableReference();
if ( primaryTableReference.getTableReference( navigablePath, tableExpression ) != null ) {
if ( primaryTableReference.getTableReference( navigablePath, tableExpression, allowFkOptimization ) != null ) {
return primaryTableReference;
}
}

View File

@ -65,7 +65,10 @@ public class CteTableGroup implements TableGroup {
}
@Override
public TableReference getTableReference(NavigablePath navigablePath, String tableExpression) {
public TableReference getTableReference(
NavigablePath navigablePath,
String tableExpression,
boolean allowFkOptimization) {
if ( cteTableReference.getTableExpression().equals( tableExpression ) ) {
return cteTableReference;
}
@ -73,7 +76,10 @@ public class CteTableGroup implements TableGroup {
}
@Override
public TableReference resolveTableReference(NavigablePath navigablePath, String tableExpression) {
public TableReference resolveTableReference(
NavigablePath navigablePath,
String tableExpression,
boolean allowFkOptimization) {
return cteTableReference;
}

View File

@ -25,10 +25,17 @@ public abstract class AbstractColumnReferenceQualifier implements ColumnReferenc
// TableReference handling
@Override
public TableReference resolveTableReference(NavigablePath navigablePath, String tableExpression) {
public TableReference resolveTableReference(
NavigablePath navigablePath,
String tableExpression,
boolean allowFkOptimization) {
assert tableExpression != null;
final TableReference tableReference = getTableReferenceInternal( navigablePath, tableExpression );
final TableReference tableReference = getTableReferenceInternal(
navigablePath,
tableExpression,
allowFkOptimization
);
if ( tableReference == null ) {
throw new IllegalStateException( "Could not resolve binding for table `" + tableExpression + "`" );
}
@ -37,14 +44,22 @@ public abstract class AbstractColumnReferenceQualifier implements ColumnReferenc
}
@Override
public TableReference getTableReference(NavigablePath navigablePath, String tableExpression) {
return getTableReferenceInternal( navigablePath, tableExpression );
public TableReference getTableReference(
NavigablePath navigablePath,
String tableExpression,
boolean allowFkOptimization) {
return getTableReferenceInternal( navigablePath, tableExpression, allowFkOptimization );
}
protected TableReference getTableReferenceInternal(
NavigablePath navigablePath,
String tableExpression) {
final TableReference primaryTableReference = getPrimaryTableReference().getTableReference( navigablePath , tableExpression );
String tableExpression,
boolean allowFkOptimization) {
final TableReference primaryTableReference = getPrimaryTableReference().getTableReference(
navigablePath,
tableExpression,
allowFkOptimization
);
if ( primaryTableReference != null) {
return primaryTableReference;
}
@ -52,7 +67,9 @@ public abstract class AbstractColumnReferenceQualifier implements ColumnReferenc
for ( TableReferenceJoin tableJoin : getTableReferenceJoins() ) {
final TableReference tableReference = tableJoin.getJoinedTableReference().getTableReference(
navigablePath,
tableExpression );
tableExpression,
allowFkOptimization
);
if ( tableReference != null) {
return tableReference;
}

View File

@ -12,9 +12,25 @@ import org.hibernate.query.NavigablePath;
* @author Steve Ebersole
*/
public interface ColumnReferenceQualifier {
TableReference resolveTableReference(NavigablePath navigablePath, String tableExpression);
TableReference getTableReference(NavigablePath navigablePath, String tableExpression);
default TableReference resolveTableReference(NavigablePath navigablePath, String tableExpression) {
return resolveTableReference( navigablePath, tableExpression, true );
}
TableReference resolveTableReference(
NavigablePath navigablePath,
String tableExpression,
boolean allowFkOptimization);
default TableReference getTableReference(NavigablePath navigablePath, String tableExpression) {
return getTableReference( navigablePath, tableExpression, true );
}
TableReference getTableReference(
NavigablePath navigablePath,
String tableExpression,
boolean allowFkOptimization);
default TableReference getTableReference(String tableExpression) {
return getTableReference( null, tableExpression );
return getTableReference( null, tableExpression, true );
}
}

View File

@ -108,18 +108,30 @@ public class CompositeTableGroup implements VirtualTableGroup {
}
@Override
public TableReference getTableReference(NavigablePath navigablePath, String tableExpression) {
return underlyingTableGroup.getTableReference( navigablePath, tableExpression );
public TableReference getTableReference(
NavigablePath navigablePath,
String tableExpression,
boolean allowFkOptimization) {
return underlyingTableGroup.getTableReference( navigablePath, tableExpression, allowFkOptimization );
}
@Override
public TableReference resolveTableReference(NavigablePath navigablePath, String tableExpression) {
TableReference tableReference = underlyingTableGroup.getTableReference( navigablePath, tableExpression );
public TableReference resolveTableReference(
NavigablePath navigablePath,
String tableExpression,
boolean allowFkOptimization) {
final TableReference tableReference = underlyingTableGroup.getTableReference(
navigablePath,
tableExpression,
allowFkOptimization
);
if ( tableReference != null ) {
return tableReference;
}
for ( TableGroupJoin tableGroupJoin : getTableGroupJoins() ) {
final TableReference primaryTableReference = tableGroupJoin.getJoinedGroup().getPrimaryTableReference().getTableReference( navigablePath, tableExpression );
final TableReference primaryTableReference = tableGroupJoin.getJoinedGroup()
.getPrimaryTableReference()
.getTableReference( navigablePath, tableExpression, allowFkOptimization );
if ( primaryTableReference != null ) {
return primaryTableReference;
}

View File

@ -61,19 +61,30 @@ public class CorrelatedTableGroup extends AbstractTableGroup {
@Override
protected TableReference getTableReferenceInternal(
NavigablePath navigablePath,
String tableExpression) {
final TableReference primaryTableReference = correlatedTableGroup.getPrimaryTableReference().getTableReference( navigablePath, tableExpression );
String tableExpression,
boolean allowFkOptimization) {
final TableReference primaryTableReference = correlatedTableGroup.getPrimaryTableReference().getTableReference(
navigablePath,
tableExpression,
allowFkOptimization
);
if ( primaryTableReference != null ) {
return primaryTableReference;
}
for ( TableGroupJoin tableGroupJoin : getTableGroupJoins() ) {
final TableReference groupTableReference = tableGroupJoin.getJoinedGroup().getPrimaryTableReference().getTableReference( navigablePath, tableExpression );
final TableReference groupTableReference = tableGroupJoin.getJoinedGroup()
.getPrimaryTableReference()
.getTableReference( navigablePath, tableExpression, allowFkOptimization );
if ( groupTableReference != null ) {
return groupTableReference;
}
}
for ( TableReferenceJoin tableReferenceJoin : correlatedTableGroup.getTableReferenceJoins() ) {
final TableReference tableReference = tableReferenceJoin.getJoinedTableReference().getTableReference( navigablePath, tableExpression );
final TableReference tableReference = tableReferenceJoin.getJoinedTableReference().getTableReference(
navigablePath,
tableExpression,
allowFkOptimization
);
if ( tableReference != null ) {
return tableReference;
}

View File

@ -158,38 +158,19 @@ public class LazyTableGroup extends AbstractColumnReferenceQualifier implements
@Override
public TableReference getTableReferenceInternal(
NavigablePath navigablePath,
String tableExpression) {
/*
todo (6.0): I think this could still return the wrong table reference in the following scenario
a self-referential many-to-one association with a non-PK FK is join fetched
The fetch for the property which is the FK target would be read from the parent which is wrong
@Entity
class Book {
@Id int id;
String isbn;
@ManyToOne
@JoinColumn(name = "parentIsbn", referenceColumnName = "isbn")
Book parentBook;
}
For data [Book(isbn=123),Book(isbn=456, parentBook=123)] the query
`from Book b join fetch b.parentBook where b.isbn = '456'`
would lead to to fetching [Book(isbn=123),Book(isbn=123, parentBook=123)].
I think the solution for this would be to pass a boolean flag to skip the parent table group,
which is always set when resolving for a fetch since the fetch needs the target property value
*/
if ( navigablePath == null || navigablePathChecker.test( navigablePath, tableExpression ) ) {
String tableExpression,
boolean allowFkOptimization) {
if ( allowFkOptimization && ( navigablePath == null || navigablePathChecker.test( navigablePath, tableExpression ) ) ) {
final TableReference reference = parentTableGroup.getTableReference(
navigablePath,
tableExpression
tableExpression,
allowFkOptimization
);
if ( reference != null ) {
return reference;
}
}
return getTableGroup().getTableReference( navigablePath, tableExpression );
return getTableGroup().getTableReference( navigablePath, tableExpression, allowFkOptimization );
}
}

View File

@ -60,15 +60,21 @@ public class MutatingTableReferenceGroupWrapper implements VirtualTableGroup {
}
@Override
public TableReference getTableReference(NavigablePath navigablePath, String tableExpression) {
public TableReference getTableReference(
NavigablePath navigablePath,
String tableExpression,
boolean allowFkOptimization) {
return mutatingTableReference.getTableExpression().equals( tableExpression )
? mutatingTableReference
: null;
}
@Override
public TableReference resolveTableReference(NavigablePath navigablePath, String tableExpression) {
return getTableReference( navigablePath, tableExpression );
public TableReference resolveTableReference(
NavigablePath navigablePath,
String tableExpression,
boolean allowFkOptimization) {
return getTableReference( navigablePath, tableExpression, allowFkOptimization );
}
@Override

View File

@ -133,8 +133,12 @@ public class StandardTableGroup extends AbstractTableGroup {
@Override
public TableReference getTableReferenceInternal(
NavigablePath navigablePath,
String tableExpression) {
TableReference tableReference = primaryTableReference.getTableReference( navigablePath, tableExpression );
String tableExpression, boolean allowFkOptimization) {
final TableReference tableReference = primaryTableReference.getTableReference(
navigablePath,
tableExpression,
allowFkOptimization
);
if ( tableReference != null ) {
return tableReference;
}
@ -145,7 +149,7 @@ public class StandardTableGroup extends AbstractTableGroup {
final TableReferenceJoin join = tableJoins.get( i );
assert join != null;
final TableReference resolveTableReference = join.getJoinedTableReference()
.getTableReference( navigablePath, tableExpression );
.getTableReference( navigablePath, tableExpression, allowFkOptimization );
if ( resolveTableReference != null ) {
return resolveTableReference;
}
@ -157,7 +161,7 @@ public class StandardTableGroup extends AbstractTableGroup {
for ( TableGroupJoin tableGroupJoin : getTableGroupJoins() ) {
final TableReference primaryTableReference = tableGroupJoin.getJoinedGroup().getPrimaryTableReference();
if ( primaryTableReference.getTableReference( navigablePath, tableExpression ) != null ) {
if ( primaryTableReference.getTableReference( navigablePath, tableExpression, allowFkOptimization ) != null ) {
return primaryTableReference;
}
}

View File

@ -52,7 +52,10 @@ public class TableReference implements SqlAstNode, ColumnReferenceQualifier {
}
@Override
public TableReference resolveTableReference(NavigablePath navigablePath, String tableExpression) {
public TableReference resolveTableReference(
NavigablePath navigablePath,
String tableExpression,
boolean allowFkOptimization) {
if ( tableExpression.equals( getTableExpression() ) ) {
return this;
}
@ -60,7 +63,10 @@ public class TableReference implements SqlAstNode, ColumnReferenceQualifier {
}
@Override
public TableReference getTableReference(NavigablePath navigablePath, String tableExpression) {
public TableReference getTableReference(
NavigablePath navigablePath,
String tableExpression,
boolean allowFkOptimization) {
if ( this.tableExpression.equals( tableExpression ) ) {
return this;
}

View File

@ -113,19 +113,25 @@ public class UnionTableGroup implements VirtualTableGroup {
}
@Override
public TableReference getTableReference(NavigablePath navigablePath, String tableExpression) {
return resolveTableReference( navigablePath, tableExpression );
public TableReference getTableReference(
NavigablePath navigablePath,
String tableExpression,
boolean allowFkOptimization) {
return resolveTableReference( navigablePath, tableExpression, allowFkOptimization );
}
@Override
public TableReference resolveTableReference(NavigablePath navigablePath, String tableExpression) {
if ( tableReference.getTableReference( navigablePath, tableExpression ) != null ) {
public TableReference resolveTableReference(
NavigablePath navigablePath,
String tableExpression,
boolean allowFkOptimization) {
if ( tableReference.getTableReference( navigablePath, tableExpression, allowFkOptimization ) != null ) {
return tableReference;
}
if ( tableGroupJoins != null ) {
for ( TableGroupJoin tableGroupJoin : tableGroupJoins ) {
final TableReference tableReference = tableGroupJoin.getJoinedGroup()
.resolveTableReference( navigablePath, tableExpression );
.resolveTableReference( navigablePath, tableExpression, allowFkOptimization );
if ( tableReference != null ) {
return tableReference;
}

View File

@ -27,7 +27,10 @@ public class UnionTableReference extends TableReference {
}
@Override
public TableReference resolveTableReference(NavigablePath navigablePath, String tableExpression) {
public TableReference resolveTableReference(
NavigablePath navigablePath,
String tableExpression,
boolean allowFkOptimization) {
if ( hasTableExpression( tableExpression ) ) {
return this;
}
@ -35,7 +38,10 @@ public class UnionTableReference extends TableReference {
}
@Override
public TableReference getTableReference(NavigablePath navigablePath, String tableExpression) {
public TableReference getTableReference(
NavigablePath navigablePath,
String tableExpression,
boolean allowFkOptimization) {
if ( hasTableExpression( tableExpression ) ) {
return this;
}

View File

@ -101,13 +101,19 @@ public class EntityCollectionPartTableGroup implements TableGroup {
}
@Override
public TableReference getTableReference(NavigablePath navigablePath, String tableExpression) {
return collectionTableGroup.getTableReference( navigablePath, tableExpression );
public TableReference getTableReference(
NavigablePath navigablePath,
String tableExpression,
boolean allowFkOptimization) {
return collectionTableGroup.getTableReference( navigablePath, tableExpression, allowFkOptimization );
}
@Override
public TableReference resolveTableReference(NavigablePath navigablePath, String tableExpression) {
return collectionTableGroup.resolveTableReference( navigablePath, tableExpression );
public TableReference resolveTableReference(
NavigablePath navigablePath,
String tableExpression,
boolean allowFkOptimization) {
return collectionTableGroup.resolveTableReference( navigablePath, tableExpression, allowFkOptimization );
}
@Override