mirror of
https://github.com/hibernate/hibernate-orm
synced 2025-02-17 00:24:57 +00:00
Fix join predicate rendering and fix support for implicit joins in the ON clause
This commit is contained in:
parent
8fc0e05930
commit
fa3101c29e
@ -42,6 +42,7 @@
|
|||||||
import org.hibernate.sql.ast.tree.from.TableGroup;
|
import org.hibernate.sql.ast.tree.from.TableGroup;
|
||||||
import org.hibernate.sql.ast.tree.from.TableGroupJoin;
|
import org.hibernate.sql.ast.tree.from.TableGroupJoin;
|
||||||
import org.hibernate.sql.ast.tree.from.TableReference;
|
import org.hibernate.sql.ast.tree.from.TableReference;
|
||||||
|
import org.hibernate.sql.ast.tree.predicate.Predicate;
|
||||||
import org.hibernate.sql.results.graph.DomainResult;
|
import org.hibernate.sql.results.graph.DomainResult;
|
||||||
import org.hibernate.sql.results.graph.DomainResultCreationState;
|
import org.hibernate.sql.results.graph.DomainResultCreationState;
|
||||||
import org.hibernate.sql.results.graph.Fetch;
|
import org.hibernate.sql.results.graph.Fetch;
|
||||||
@ -173,19 +174,38 @@ public TableGroupJoin createTableGroupJoin(
|
|||||||
SqlAliasBaseGenerator aliasBaseGenerator,
|
SqlAliasBaseGenerator aliasBaseGenerator,
|
||||||
SqlExpressionResolver sqlExpressionResolver,
|
SqlExpressionResolver sqlExpressionResolver,
|
||||||
SqlAstCreationContext creationContext) {
|
SqlAstCreationContext creationContext) {
|
||||||
final CompositeTableGroup compositeTableGroup = new CompositeTableGroup(
|
final TableGroup tableGroup = createRootTableGroupJoin(
|
||||||
navigablePath,
|
navigablePath,
|
||||||
this,
|
|
||||||
lhs,
|
lhs,
|
||||||
fetched
|
explicitSourceAlias,
|
||||||
|
sqlAstJoinType,
|
||||||
|
fetched,
|
||||||
|
null,
|
||||||
|
aliasBaseGenerator,
|
||||||
|
sqlExpressionResolver,
|
||||||
|
creationContext
|
||||||
);
|
);
|
||||||
|
|
||||||
final TableGroupJoin join = new TableGroupJoin( navigablePath, SqlAstJoinType.LEFT, compositeTableGroup, null );
|
final TableGroupJoin join = new TableGroupJoin( navigablePath, SqlAstJoinType.LEFT, tableGroup, null );
|
||||||
lhs.addTableGroupJoin( join );
|
lhs.addTableGroupJoin( join );
|
||||||
|
|
||||||
return join;
|
return join;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public TableGroup createRootTableGroupJoin(
|
||||||
|
NavigablePath navigablePath,
|
||||||
|
TableGroup lhs,
|
||||||
|
String explicitSourceAlias,
|
||||||
|
SqlAstJoinType sqlAstJoinType,
|
||||||
|
boolean fetched,
|
||||||
|
Consumer<Predicate> predicateConsumer,
|
||||||
|
SqlAliasBaseGenerator aliasBaseGenerator,
|
||||||
|
SqlExpressionResolver sqlExpressionResolver,
|
||||||
|
SqlAstCreationContext creationContext) {
|
||||||
|
return new CompositeTableGroup( navigablePath, this, lhs, fetched );
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ModelPart findSubPart(String name, EntityMappingType treatTargetType) {
|
public ModelPart findSubPart(String name, EntityMappingType treatTargetType) {
|
||||||
return embeddableDescriptor.findSubPart( name, treatTargetType );
|
return embeddableDescriptor.findSubPart( name, treatTargetType );
|
||||||
|
@ -44,6 +44,7 @@
|
|||||||
import org.hibernate.sql.ast.tree.from.TableGroup;
|
import org.hibernate.sql.ast.tree.from.TableGroup;
|
||||||
import org.hibernate.sql.ast.tree.from.TableGroupJoin;
|
import org.hibernate.sql.ast.tree.from.TableGroupJoin;
|
||||||
import org.hibernate.sql.ast.tree.from.TableReference;
|
import org.hibernate.sql.ast.tree.from.TableReference;
|
||||||
|
import org.hibernate.sql.ast.tree.predicate.Predicate;
|
||||||
import org.hibernate.sql.results.graph.DomainResult;
|
import org.hibernate.sql.results.graph.DomainResult;
|
||||||
import org.hibernate.sql.results.graph.DomainResultCreationState;
|
import org.hibernate.sql.results.graph.DomainResultCreationState;
|
||||||
import org.hibernate.sql.results.graph.Fetch;
|
import org.hibernate.sql.results.graph.Fetch;
|
||||||
@ -286,21 +287,45 @@ public TableGroupJoin createTableGroupJoin(
|
|||||||
SqlAliasBaseGenerator aliasBaseGenerator,
|
SqlAliasBaseGenerator aliasBaseGenerator,
|
||||||
SqlExpressionResolver sqlExpressionResolver,
|
SqlExpressionResolver sqlExpressionResolver,
|
||||||
SqlAstCreationContext creationContext) {
|
SqlAstCreationContext creationContext) {
|
||||||
final CompositeTableGroup compositeTableGroup = new CompositeTableGroup(
|
final TableGroup tableGroup = createRootTableGroupJoin(
|
||||||
|
navigablePath,
|
||||||
|
lhs,
|
||||||
|
explicitSourceAlias,
|
||||||
|
sqlAstJoinType,
|
||||||
|
fetched,
|
||||||
|
null,
|
||||||
|
aliasBaseGenerator,
|
||||||
|
sqlExpressionResolver,
|
||||||
|
creationContext
|
||||||
|
);
|
||||||
|
|
||||||
|
final TableGroupJoin tableGroupJoin = new TableGroupJoin(
|
||||||
|
navigablePath,
|
||||||
|
sqlAstJoinType,
|
||||||
|
tableGroup
|
||||||
|
);
|
||||||
|
lhs.addTableGroupJoin( tableGroupJoin );
|
||||||
|
|
||||||
|
return tableGroupJoin;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public TableGroup createRootTableGroupJoin(
|
||||||
|
NavigablePath navigablePath,
|
||||||
|
TableGroup lhs,
|
||||||
|
String explicitSourceAlias,
|
||||||
|
SqlAstJoinType sqlAstJoinType,
|
||||||
|
boolean fetched,
|
||||||
|
Consumer<Predicate> predicateConsumer,
|
||||||
|
SqlAliasBaseGenerator aliasBaseGenerator,
|
||||||
|
SqlExpressionResolver sqlExpressionResolver,
|
||||||
|
SqlAstCreationContext creationContext) {
|
||||||
|
return new CompositeTableGroup(
|
||||||
navigablePath,
|
navigablePath,
|
||||||
this,
|
this,
|
||||||
lhs,
|
lhs,
|
||||||
fetched
|
fetched
|
||||||
);
|
);
|
||||||
|
|
||||||
TableGroupJoin tableGroupJoin = new TableGroupJoin(
|
|
||||||
navigablePath,
|
|
||||||
sqlAstJoinType,
|
|
||||||
compositeTableGroup
|
|
||||||
);
|
|
||||||
lhs.addTableGroupJoin( tableGroupJoin );
|
|
||||||
|
|
||||||
return tableGroupJoin;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -40,6 +40,7 @@
|
|||||||
import org.hibernate.sql.ast.tree.from.CompositeTableGroup;
|
import org.hibernate.sql.ast.tree.from.CompositeTableGroup;
|
||||||
import org.hibernate.sql.ast.tree.from.TableGroup;
|
import org.hibernate.sql.ast.tree.from.TableGroup;
|
||||||
import org.hibernate.sql.ast.tree.from.TableGroupJoin;
|
import org.hibernate.sql.ast.tree.from.TableGroupJoin;
|
||||||
|
import org.hibernate.sql.ast.tree.predicate.Predicate;
|
||||||
import org.hibernate.sql.results.graph.DomainResult;
|
import org.hibernate.sql.results.graph.DomainResult;
|
||||||
import org.hibernate.sql.results.graph.DomainResultCreationState;
|
import org.hibernate.sql.results.graph.DomainResultCreationState;
|
||||||
import org.hibernate.sql.results.graph.Fetch;
|
import org.hibernate.sql.results.graph.Fetch;
|
||||||
@ -204,9 +205,17 @@ public TableGroupJoin createTableGroupJoin(
|
|||||||
SqlAliasBaseGenerator aliasBaseGenerator,
|
SqlAliasBaseGenerator aliasBaseGenerator,
|
||||||
SqlExpressionResolver sqlExpressionResolver,
|
SqlExpressionResolver sqlExpressionResolver,
|
||||||
SqlAstCreationContext creationContext) {
|
SqlAstCreationContext creationContext) {
|
||||||
assert lhs.getModelPart() instanceof PluralAttributeMapping;
|
final TableGroup tableGroup = createRootTableGroupJoin(
|
||||||
|
navigablePath,
|
||||||
final TableGroup tableGroup = new CompositeTableGroup( navigablePath, this, lhs, fetched );
|
lhs,
|
||||||
|
explicitSourceAlias,
|
||||||
|
sqlAstJoinType,
|
||||||
|
fetched,
|
||||||
|
null,
|
||||||
|
aliasBaseGenerator,
|
||||||
|
sqlExpressionResolver,
|
||||||
|
creationContext
|
||||||
|
);
|
||||||
|
|
||||||
final TableGroupJoin tableGroupJoin = new TableGroupJoin(
|
final TableGroupJoin tableGroupJoin = new TableGroupJoin(
|
||||||
navigablePath,
|
navigablePath,
|
||||||
@ -218,6 +227,22 @@ public TableGroupJoin createTableGroupJoin(
|
|||||||
return tableGroupJoin;
|
return tableGroupJoin;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public TableGroup createRootTableGroupJoin(
|
||||||
|
NavigablePath navigablePath,
|
||||||
|
TableGroup lhs,
|
||||||
|
String explicitSourceAlias,
|
||||||
|
SqlAstJoinType sqlAstJoinType,
|
||||||
|
boolean fetched,
|
||||||
|
Consumer<Predicate> predicateConsumer,
|
||||||
|
SqlAliasBaseGenerator aliasBaseGenerator,
|
||||||
|
SqlExpressionResolver sqlExpressionResolver,
|
||||||
|
SqlAstCreationContext creationContext) {
|
||||||
|
assert lhs.getModelPart() instanceof PluralAttributeMapping;
|
||||||
|
|
||||||
|
return new CompositeTableGroup( navigablePath, this, lhs, fetched );
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getSqlAliasStem() {
|
public String getSqlAliasStem() {
|
||||||
return sqlAliasStem;
|
return sqlAliasStem;
|
||||||
|
@ -335,31 +335,16 @@ private <T> DomainResult<T> createDomainResult(
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Predicate generateJoinPredicate(
|
public Predicate generateJoinPredicate(
|
||||||
TableGroup lhs,
|
TableGroup targetSideTableGroup,
|
||||||
TableGroup tableGroup,
|
TableGroup keySideTableGroup,
|
||||||
SqlAstJoinType sqlAstJoinType,
|
SqlAstJoinType sqlAstJoinType,
|
||||||
SqlExpressionResolver sqlExpressionResolver,
|
SqlExpressionResolver sqlExpressionResolver,
|
||||||
SqlAstCreationContext creationContext) {
|
SqlAstCreationContext creationContext) {
|
||||||
TableReference lhsTableReference;
|
final TableReference lhsTableReference = targetSideTableGroup.getTableReference(
|
||||||
TableReference rhsTableKeyReference;
|
targetSideTableGroup.getNavigablePath(),
|
||||||
if ( targetTable.equals( keyTable ) ) {
|
|
||||||
lhsTableReference = getTableReferenceWhenTargetEqualsKey( lhs, tableGroup, keyTable );
|
|
||||||
|
|
||||||
rhsTableKeyReference = getTableReference(
|
|
||||||
lhs,
|
|
||||||
tableGroup,
|
|
||||||
targetTable
|
targetTable
|
||||||
);
|
);
|
||||||
}
|
final TableReference rhsTableKeyReference = keySideTableGroup.getTableReference( keyTable );
|
||||||
else {
|
|
||||||
lhsTableReference = getTableReference( lhs, tableGroup, keyTable );
|
|
||||||
|
|
||||||
rhsTableKeyReference = getTableReference(
|
|
||||||
lhs,
|
|
||||||
tableGroup,
|
|
||||||
targetTable
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
return generateJoinPredicate(
|
return generateJoinPredicate(
|
||||||
lhsTableReference,
|
lhsTableReference,
|
||||||
@ -372,21 +357,12 @@ public Predicate generateJoinPredicate(
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Predicate generateJoinPredicate(
|
public Predicate generateJoinPredicate(
|
||||||
TableReference lhs,
|
TableReference targetSideReference,
|
||||||
TableReference rhs,
|
TableReference keySideReference,
|
||||||
SqlAstJoinType sqlAstJoinType,
|
SqlAstJoinType sqlAstJoinType,
|
||||||
SqlExpressionResolver sqlExpressionResolver,
|
SqlExpressionResolver sqlExpressionResolver,
|
||||||
SqlAstCreationContext creationContext) {
|
SqlAstCreationContext creationContext) {
|
||||||
final String rhsTableExpression = rhs.getTableExpression();
|
return getPredicate( targetSideReference, keySideReference, creationContext, targetSelectableMappings, keySelectableMappings );
|
||||||
final String lhsTableExpression = lhs.getTableExpression();
|
|
||||||
if ( lhsTableExpression.equals( keyTable ) ) {
|
|
||||||
assert rhsTableExpression.equals( targetTable );
|
|
||||||
return getPredicate( lhs, rhs, creationContext, keySelectableMappings, targetSelectableMappings );
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
assert rhsTableExpression.equals( keyTable );
|
|
||||||
return getPredicate( lhs, rhs, creationContext, targetSelectableMappings, keySelectableMappings );
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private Predicate getPredicate(
|
private Predicate getPredicate(
|
||||||
@ -417,23 +393,6 @@ private Predicate getPredicate(
|
|||||||
return predicate;
|
return predicate;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected TableReference getTableReferenceWhenTargetEqualsKey(TableGroup lhs, TableGroup tableGroup, String table) {
|
|
||||||
if ( tableGroup.getPrimaryTableReference().getTableExpression().equals( table ) ) {
|
|
||||||
return tableGroup.getPrimaryTableReference();
|
|
||||||
}
|
|
||||||
if ( lhs.getPrimaryTableReference().getTableExpression().equals( table ) ) {
|
|
||||||
return lhs.getPrimaryTableReference();
|
|
||||||
}
|
|
||||||
|
|
||||||
for ( TableReferenceJoin tableJoin : lhs.getTableReferenceJoins() ) {
|
|
||||||
if ( tableJoin.getJoinedTableReference().getTableExpression().equals( table ) ) {
|
|
||||||
return tableJoin.getJoinedTableReference();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
throw new IllegalStateException( "Could not resolve binding for table `" + table + "`" );
|
|
||||||
}
|
|
||||||
|
|
||||||
protected TableReference getTableReference(TableGroup lhs, TableGroup tableGroup, String table) {
|
protected TableReference getTableReference(TableGroup lhs, TableGroup tableGroup, String table) {
|
||||||
if ( lhs.getPrimaryTableReference().getTableExpression().equals( table ) ) {
|
if ( lhs.getPrimaryTableReference().getTableExpression().equals( table ) ) {
|
||||||
return lhs.getPrimaryTableReference();
|
return lhs.getPrimaryTableReference();
|
||||||
|
@ -7,6 +7,7 @@
|
|||||||
package org.hibernate.metamodel.mapping.internal;
|
package org.hibernate.metamodel.mapping.internal;
|
||||||
|
|
||||||
import java.util.function.BiConsumer;
|
import java.util.function.BiConsumer;
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
import org.hibernate.engine.FetchStyle;
|
import org.hibernate.engine.FetchStyle;
|
||||||
import org.hibernate.engine.FetchTiming;
|
import org.hibernate.engine.FetchTiming;
|
||||||
@ -32,6 +33,7 @@
|
|||||||
import org.hibernate.sql.ast.spi.SqlSelection;
|
import org.hibernate.sql.ast.spi.SqlSelection;
|
||||||
import org.hibernate.sql.ast.tree.from.TableGroup;
|
import org.hibernate.sql.ast.tree.from.TableGroup;
|
||||||
import org.hibernate.sql.ast.tree.from.TableGroupJoin;
|
import org.hibernate.sql.ast.tree.from.TableGroupJoin;
|
||||||
|
import org.hibernate.sql.ast.tree.predicate.Predicate;
|
||||||
import org.hibernate.sql.results.graph.DomainResult;
|
import org.hibernate.sql.results.graph.DomainResult;
|
||||||
import org.hibernate.sql.results.graph.DomainResultCreationState;
|
import org.hibernate.sql.results.graph.DomainResultCreationState;
|
||||||
import org.hibernate.sql.results.graph.FetchOptions;
|
import org.hibernate.sql.results.graph.FetchOptions;
|
||||||
@ -286,6 +288,30 @@ public TableGroupJoin createTableGroupJoin(
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public TableGroup createRootTableGroupJoin(
|
||||||
|
NavigablePath navigablePath,
|
||||||
|
TableGroup lhs,
|
||||||
|
String explicitSourceAlias,
|
||||||
|
SqlAstJoinType sqlAstJoinType,
|
||||||
|
boolean fetched,
|
||||||
|
Consumer<Predicate> predicateConsumer,
|
||||||
|
SqlAliasBaseGenerator aliasBaseGenerator,
|
||||||
|
SqlExpressionResolver sqlExpressionResolver,
|
||||||
|
SqlAstCreationContext creationContext) {
|
||||||
|
return collectionDescriptor.getAttributeMapping().createRootTableGroupJoin(
|
||||||
|
navigablePath,
|
||||||
|
lhs,
|
||||||
|
explicitSourceAlias,
|
||||||
|
sqlAstJoinType,
|
||||||
|
fetched,
|
||||||
|
predicateConsumer,
|
||||||
|
aliasBaseGenerator,
|
||||||
|
sqlExpressionResolver,
|
||||||
|
creationContext
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getSqlAliasStem() {
|
public String getSqlAliasStem() {
|
||||||
return collectionDescriptor.getAttributeMapping().getSqlAliasStem();
|
return collectionDescriptor.getAttributeMapping().getSqlAliasStem();
|
||||||
|
@ -627,57 +627,17 @@ public TableGroupJoin createTableGroupJoin(
|
|||||||
SqlAliasBaseGenerator aliasBaseGenerator,
|
SqlAliasBaseGenerator aliasBaseGenerator,
|
||||||
SqlExpressionResolver sqlExpressionResolver,
|
SqlExpressionResolver sqlExpressionResolver,
|
||||||
SqlAstCreationContext creationContext) {
|
SqlAstCreationContext creationContext) {
|
||||||
final CollectionPersister collectionDescriptor = getCollectionDescriptor();
|
final TableGroup tableGroup = createRootTableGroupJoin(
|
||||||
if ( collectionDescriptor.isOneToMany() ) {
|
|
||||||
return createOneToManyTableGroupJoin(
|
|
||||||
navigablePath,
|
navigablePath,
|
||||||
lhs,
|
lhs,
|
||||||
explicitSourceAlias,
|
explicitSourceAlias,
|
||||||
sqlAstJoinType,
|
sqlAstJoinType,
|
||||||
fetched,
|
fetched,
|
||||||
|
null,
|
||||||
aliasBaseGenerator,
|
aliasBaseGenerator,
|
||||||
sqlExpressionResolver,
|
sqlExpressionResolver,
|
||||||
creationContext
|
creationContext
|
||||||
);
|
);
|
||||||
}
|
|
||||||
else {
|
|
||||||
return createCollectionTableGroupJoin(
|
|
||||||
navigablePath,
|
|
||||||
lhs,
|
|
||||||
explicitSourceAlias,
|
|
||||||
sqlAstJoinType,
|
|
||||||
fetched,
|
|
||||||
aliasBaseGenerator,
|
|
||||||
sqlExpressionResolver,
|
|
||||||
creationContext
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setForeignKeyDescriptor(ForeignKeyDescriptor fkDescriptor) {
|
|
||||||
this.fkDescriptor = fkDescriptor;
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressWarnings("unused")
|
|
||||||
private TableGroupJoin createOneToManyTableGroupJoin(
|
|
||||||
NavigablePath navigablePath,
|
|
||||||
TableGroup lhs,
|
|
||||||
String explicitSourceAlias,
|
|
||||||
SqlAstJoinType sqlAstJoinType,
|
|
||||||
boolean fetched,
|
|
||||||
SqlAliasBaseGenerator aliasBaseGenerator,
|
|
||||||
SqlExpressionResolver sqlExpressionResolver,
|
|
||||||
SqlAstCreationContext creationContext) {
|
|
||||||
final TableGroup tableGroup = createOneToManyTableGroup(
|
|
||||||
lhs.canUseInnerJoins() && sqlAstJoinType == SqlAstJoinType.INNER,
|
|
||||||
navigablePath,
|
|
||||||
fetched,
|
|
||||||
explicitSourceAlias,
|
|
||||||
aliasBaseGenerator.createSqlAliasBase( getSqlAliasStem() ),
|
|
||||||
sqlExpressionResolver,
|
|
||||||
creationContext
|
|
||||||
);
|
|
||||||
|
|
||||||
final TableGroupJoin tableGroupJoin = new TableGroupJoin(
|
final TableGroupJoin tableGroupJoin = new TableGroupJoin(
|
||||||
navigablePath,
|
navigablePath,
|
||||||
sqlAstJoinType,
|
sqlAstJoinType,
|
||||||
@ -696,6 +656,60 @@ private TableGroupJoin createOneToManyTableGroupJoin(
|
|||||||
return tableGroupJoin;
|
return tableGroupJoin;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public TableGroup createRootTableGroupJoin(
|
||||||
|
NavigablePath navigablePath,
|
||||||
|
TableGroup lhs,
|
||||||
|
String explicitSourceAlias,
|
||||||
|
SqlAstJoinType sqlAstJoinType,
|
||||||
|
boolean fetched,
|
||||||
|
Consumer<Predicate> predicateConsumer,
|
||||||
|
SqlAliasBaseGenerator aliasBaseGenerator,
|
||||||
|
SqlExpressionResolver sqlExpressionResolver,
|
||||||
|
SqlAstCreationContext creationContext) {
|
||||||
|
final CollectionPersister collectionDescriptor = getCollectionDescriptor();
|
||||||
|
final TableGroup tableGroup;
|
||||||
|
if ( collectionDescriptor.isOneToMany() ) {
|
||||||
|
tableGroup = createOneToManyTableGroup(
|
||||||
|
lhs.canUseInnerJoins() && sqlAstJoinType == SqlAstJoinType.INNER,
|
||||||
|
navigablePath,
|
||||||
|
fetched,
|
||||||
|
explicitSourceAlias,
|
||||||
|
aliasBaseGenerator.createSqlAliasBase( getSqlAliasStem() ),
|
||||||
|
sqlExpressionResolver,
|
||||||
|
creationContext
|
||||||
|
);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
tableGroup = createCollectionTableGroup(
|
||||||
|
lhs.canUseInnerJoins() && sqlAstJoinType == SqlAstJoinType.INNER,
|
||||||
|
navigablePath,
|
||||||
|
fetched,
|
||||||
|
explicitSourceAlias,
|
||||||
|
aliasBaseGenerator.createSqlAliasBase( getSqlAliasStem() ),
|
||||||
|
sqlExpressionResolver,
|
||||||
|
creationContext
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( predicateConsumer != null ) {
|
||||||
|
predicateConsumer.accept(
|
||||||
|
getKeyDescriptor().generateJoinPredicate(
|
||||||
|
lhs,
|
||||||
|
tableGroup,
|
||||||
|
sqlAstJoinType,
|
||||||
|
sqlExpressionResolver,
|
||||||
|
creationContext
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return tableGroup;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setForeignKeyDescriptor(ForeignKeyDescriptor fkDescriptor) {
|
||||||
|
this.fkDescriptor = fkDescriptor;
|
||||||
|
}
|
||||||
|
|
||||||
private TableGroup createOneToManyTableGroup(
|
private TableGroup createOneToManyTableGroup(
|
||||||
boolean canUseInnerJoins,
|
boolean canUseInnerJoins,
|
||||||
NavigablePath navigablePath,
|
NavigablePath navigablePath,
|
||||||
@ -825,44 +839,6 @@ else if ( indexDescriptorEntityMappingType.containsTableReference( tableExpressi
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unused")
|
|
||||||
private TableGroupJoin createCollectionTableGroupJoin(
|
|
||||||
NavigablePath navigablePath,
|
|
||||||
TableGroup lhs,
|
|
||||||
String explicitSourceAlias,
|
|
||||||
SqlAstJoinType sqlAstJoinType,
|
|
||||||
boolean fetched,
|
|
||||||
SqlAliasBaseGenerator aliasBaseGenerator,
|
|
||||||
SqlExpressionResolver sqlExpressionResolver,
|
|
||||||
SqlAstCreationContext creationContext) {
|
|
||||||
final TableGroup tableGroup = createCollectionTableGroup(
|
|
||||||
lhs.canUseInnerJoins() && sqlAstJoinType == SqlAstJoinType.INNER,
|
|
||||||
navigablePath,
|
|
||||||
fetched,
|
|
||||||
explicitSourceAlias,
|
|
||||||
aliasBaseGenerator.createSqlAliasBase( getSqlAliasStem() ),
|
|
||||||
sqlExpressionResolver,
|
|
||||||
creationContext
|
|
||||||
);
|
|
||||||
|
|
||||||
final TableGroupJoin tableGroupJoin = new TableGroupJoin(
|
|
||||||
navigablePath,
|
|
||||||
sqlAstJoinType,
|
|
||||||
tableGroup,
|
|
||||||
getKeyDescriptor().generateJoinPredicate(
|
|
||||||
lhs,
|
|
||||||
tableGroup,
|
|
||||||
sqlAstJoinType,
|
|
||||||
sqlExpressionResolver,
|
|
||||||
creationContext
|
|
||||||
)
|
|
||||||
);
|
|
||||||
|
|
||||||
lhs.addTableGroupJoin( tableGroupJoin );
|
|
||||||
|
|
||||||
return tableGroupJoin;
|
|
||||||
}
|
|
||||||
|
|
||||||
private TableGroup createCollectionTableGroup(
|
private TableGroup createCollectionTableGroup(
|
||||||
boolean canUseInnerJoins,
|
boolean canUseInnerJoins,
|
||||||
NavigablePath navigablePath,
|
NavigablePath navigablePath,
|
||||||
@ -1054,8 +1030,8 @@ private Function<TableGroup, TableReferenceJoin> createTableGroupFinalizer(
|
|||||||
joinType,
|
joinType,
|
||||||
elementAssociatedPrimaryTable,
|
elementAssociatedPrimaryTable,
|
||||||
elementFkDescriptor.generateJoinPredicate(
|
elementFkDescriptor.generateJoinPredicate(
|
||||||
collectionTableReference,
|
|
||||||
elementAssociatedPrimaryTable,
|
elementAssociatedPrimaryTable,
|
||||||
|
collectionTableReference,
|
||||||
joinType,
|
joinType,
|
||||||
sqlExpressionResolver,
|
sqlExpressionResolver,
|
||||||
creationContext
|
creationContext
|
||||||
|
@ -242,70 +242,40 @@ private <T> DomainResult<T> createDomainResult(
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Predicate generateJoinPredicate(
|
public Predicate generateJoinPredicate(
|
||||||
TableReference lhs,
|
TableReference targetSideReference,
|
||||||
TableReference rhs,
|
TableReference keySideReference,
|
||||||
SqlAstJoinType sqlAstJoinType,
|
SqlAstJoinType sqlAstJoinType,
|
||||||
SqlExpressionResolver sqlExpressionResolver,
|
SqlExpressionResolver sqlExpressionResolver,
|
||||||
SqlAstCreationContext creationContext) {
|
SqlAstCreationContext creationContext) {
|
||||||
if ( lhs.getTableReference( keySide.getModelPart().getContainingTableExpression() ) != null ) {
|
|
||||||
return new ComparisonPredicate(
|
return new ComparisonPredicate(
|
||||||
new ColumnReference(
|
new ColumnReference(
|
||||||
lhs,
|
targetSideReference,
|
||||||
keySide.getModelPart(),
|
|
||||||
creationContext.getSessionFactory()
|
|
||||||
),
|
|
||||||
ComparisonOperator.EQUAL,
|
|
||||||
new ColumnReference(
|
|
||||||
rhs,
|
|
||||||
targetSide.getModelPart(),
|
|
||||||
creationContext.getSessionFactory()
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return new ComparisonPredicate(
|
|
||||||
new ColumnReference(
|
|
||||||
lhs,
|
|
||||||
targetSide.getModelPart(),
|
targetSide.getModelPart(),
|
||||||
creationContext.getSessionFactory()
|
creationContext.getSessionFactory()
|
||||||
),
|
),
|
||||||
ComparisonOperator.EQUAL,
|
ComparisonOperator.EQUAL,
|
||||||
new ColumnReference(
|
new ColumnReference(
|
||||||
rhs,
|
keySideReference,
|
||||||
keySide.getModelPart(),
|
keySide.getModelPart(),
|
||||||
creationContext.getSessionFactory()
|
creationContext.getSessionFactory()
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Predicate generateJoinPredicate(
|
public Predicate generateJoinPredicate(
|
||||||
TableGroup lhs,
|
TableGroup targetSideTableGroup,
|
||||||
TableGroup tableGroup,
|
TableGroup keySideTableGroup,
|
||||||
SqlAstJoinType sqlAstJoinType,
|
SqlAstJoinType sqlAstJoinType,
|
||||||
SqlExpressionResolver sqlExpressionResolver,
|
SqlExpressionResolver sqlExpressionResolver,
|
||||||
SqlAstCreationContext creationContext) {
|
SqlAstCreationContext creationContext) {
|
||||||
TableReference lhsTableReference;
|
final TableReference lhsTableReference = targetSideTableGroup.getTableReference(
|
||||||
TableReference rhsTableKeyReference;
|
targetSideTableGroup.getNavigablePath(),
|
||||||
if ( targetSide.getModelPart().getContainingTableExpression().equals( keySide.getModelPart().getContainingTableExpression() ) ) {
|
|
||||||
lhsTableReference = getTableReferenceWhenTargetEqualsKey( lhs, tableGroup, keySide.getModelPart().getContainingTableExpression() );
|
|
||||||
|
|
||||||
rhsTableKeyReference = getTableReference(
|
|
||||||
lhs,
|
|
||||||
tableGroup,
|
|
||||||
targetSide.getModelPart().getContainingTableExpression()
|
targetSide.getModelPart().getContainingTableExpression()
|
||||||
);
|
);
|
||||||
}
|
final TableReference rhsTableKeyReference = keySideTableGroup.getTableReference(
|
||||||
else {
|
keySide.getModelPart().getContainingTableExpression()
|
||||||
lhsTableReference = getTableReference( lhs, tableGroup, keySide.getModelPart().getContainingTableExpression() );
|
|
||||||
|
|
||||||
rhsTableKeyReference = getTableReference(
|
|
||||||
lhs,
|
|
||||||
tableGroup,
|
|
||||||
targetSide.getModelPart().getContainingTableExpression()
|
|
||||||
);
|
);
|
||||||
}
|
|
||||||
|
|
||||||
return generateJoinPredicate(
|
return generateJoinPredicate(
|
||||||
lhsTableReference,
|
lhsTableReference,
|
||||||
@ -316,23 +286,6 @@ public Predicate generateJoinPredicate(
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected TableReference getTableReferenceWhenTargetEqualsKey(TableGroup lhs, TableGroup tableGroup, String table) {
|
|
||||||
if ( tableGroup.getPrimaryTableReference().getTableExpression().equals( table ) ) {
|
|
||||||
return tableGroup.getPrimaryTableReference();
|
|
||||||
}
|
|
||||||
if ( lhs.getPrimaryTableReference().getTableExpression().equals( table ) ) {
|
|
||||||
return lhs.getPrimaryTableReference();
|
|
||||||
}
|
|
||||||
|
|
||||||
for ( TableReferenceJoin tableJoin : lhs.getTableReferenceJoins() ) {
|
|
||||||
if ( tableJoin.getJoinedTableReference().getTableExpression().equals( table ) ) {
|
|
||||||
return tableJoin.getJoinedTableReference();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
throw new IllegalStateException( "Could not resolve binding for table `" + table + "`" );
|
|
||||||
}
|
|
||||||
|
|
||||||
protected TableReference getTableReference(TableGroup lhs, TableGroup tableGroup, String table) {
|
protected TableReference getTableReference(TableGroup lhs, TableGroup tableGroup, String table) {
|
||||||
final NavigablePath navigablePath = lhs.getNavigablePath().append( getNavigableRole().getNavigableName() );
|
final NavigablePath navigablePath = lhs.getNavigablePath().append( getNavigableRole().getNavigableName() );
|
||||||
if ( lhs.getPrimaryTableReference().getTableReference( navigablePath, table ) != null ) {
|
if ( lhs.getPrimaryTableReference().getTableReference( navigablePath, table ) != null ) {
|
||||||
|
@ -10,6 +10,7 @@
|
|||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
import org.hibernate.LockMode;
|
import org.hibernate.LockMode;
|
||||||
import org.hibernate.engine.FetchStyle;
|
import org.hibernate.engine.FetchStyle;
|
||||||
@ -56,6 +57,7 @@
|
|||||||
import org.hibernate.sql.ast.tree.from.TableGroupJoinProducer;
|
import org.hibernate.sql.ast.tree.from.TableGroupJoinProducer;
|
||||||
import org.hibernate.sql.ast.tree.from.TableGroupProducer;
|
import org.hibernate.sql.ast.tree.from.TableGroupProducer;
|
||||||
import org.hibernate.sql.ast.tree.from.TableReference;
|
import org.hibernate.sql.ast.tree.from.TableReference;
|
||||||
|
import org.hibernate.sql.ast.tree.predicate.Predicate;
|
||||||
import org.hibernate.sql.results.graph.DomainResult;
|
import org.hibernate.sql.results.graph.DomainResult;
|
||||||
import org.hibernate.sql.results.graph.DomainResultCreationState;
|
import org.hibernate.sql.results.graph.DomainResultCreationState;
|
||||||
import org.hibernate.sql.results.graph.Fetch;
|
import org.hibernate.sql.results.graph.Fetch;
|
||||||
@ -421,6 +423,10 @@ public String getTargetKeyPropertyName() {
|
|||||||
return targetKeyPropertyName;
|
return targetKeyPropertyName;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isTargetKeyPropertyPath(String path) {
|
||||||
|
return targetKeyPropertyNames.contains( path );
|
||||||
|
}
|
||||||
|
|
||||||
public Cardinality getCardinality() {
|
public Cardinality getCardinality() {
|
||||||
return cardinality;
|
return cardinality;
|
||||||
}
|
}
|
||||||
@ -924,6 +930,59 @@ public TableGroupJoin createTableGroupJoin(
|
|||||||
SqlAliasBaseGenerator aliasBaseGenerator,
|
SqlAliasBaseGenerator aliasBaseGenerator,
|
||||||
SqlExpressionResolver sqlExpressionResolver,
|
SqlExpressionResolver sqlExpressionResolver,
|
||||||
SqlAstCreationContext creationContext) {
|
SqlAstCreationContext creationContext) {
|
||||||
|
|
||||||
|
final LazyTableGroup lazyTableGroup = createRootTableGroupJoin(
|
||||||
|
navigablePath,
|
||||||
|
lhs,
|
||||||
|
explicitSourceAlias,
|
||||||
|
sqlAstJoinType,
|
||||||
|
fetched,
|
||||||
|
null,
|
||||||
|
aliasBaseGenerator,
|
||||||
|
sqlExpressionResolver,
|
||||||
|
creationContext
|
||||||
|
);
|
||||||
|
final TableGroupJoin tableGroupJoin = new TableGroupJoin(
|
||||||
|
navigablePath,
|
||||||
|
sqlAstJoinType,
|
||||||
|
lazyTableGroup,
|
||||||
|
null
|
||||||
|
);
|
||||||
|
|
||||||
|
final TableReference lhsTableReference = lhs.resolveTableReference( navigablePath, identifyingColumnsTableExpression );
|
||||||
|
|
||||||
|
lazyTableGroup.setTableGroupInitializerCallback(
|
||||||
|
tableGroup -> tableGroupJoin.applyPredicate(
|
||||||
|
foreignKeyDescriptor.generateJoinPredicate(
|
||||||
|
sideNature == ForeignKeyDescriptor.Nature.TARGET ? lhsTableReference : tableGroup.getPrimaryTableReference(),
|
||||||
|
sideNature == ForeignKeyDescriptor.Nature.TARGET ? tableGroup.getPrimaryTableReference() : lhsTableReference,
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public LazyTableGroup createRootTableGroupJoin(
|
||||||
|
NavigablePath navigablePath,
|
||||||
|
TableGroup lhs,
|
||||||
|
String explicitSourceAlias,
|
||||||
|
SqlAstJoinType sqlAstJoinType,
|
||||||
|
boolean fetched,
|
||||||
|
Consumer<Predicate> predicateConsumer,
|
||||||
|
SqlAliasBaseGenerator aliasBaseGenerator,
|
||||||
|
SqlExpressionResolver sqlExpressionResolver,
|
||||||
|
SqlAstCreationContext creationContext) {
|
||||||
final SqlAliasBase sqlAliasBase = aliasBaseGenerator.createSqlAliasBase( sqlAliasStem );
|
final SqlAliasBase sqlAliasBase = aliasBaseGenerator.createSqlAliasBase( sqlAliasStem );
|
||||||
final boolean canUseInnerJoin = sqlAstJoinType == SqlAstJoinType.INNER || lhs.canUseInnerJoins() && !isNullable;
|
final boolean canUseInnerJoin = sqlAstJoinType == SqlAstJoinType.INNER || lhs.canUseInnerJoins() && !isNullable;
|
||||||
final LazyTableGroup lazyTableGroup = new LazyTableGroup(
|
final LazyTableGroup lazyTableGroup = new LazyTableGroup(
|
||||||
@ -967,34 +1026,31 @@ public TableGroupJoin createTableGroupJoin(
|
|||||||
lhs
|
lhs
|
||||||
);
|
);
|
||||||
|
|
||||||
final TableGroupJoin tableGroupJoin = new TableGroupJoin(
|
if ( predicateConsumer != null ) {
|
||||||
|
final TableReference lhsTableReference = lhs.resolveTableReference(
|
||||||
navigablePath,
|
navigablePath,
|
||||||
sqlAstJoinType,
|
identifyingColumnsTableExpression
|
||||||
lazyTableGroup,
|
|
||||||
null
|
|
||||||
);
|
);
|
||||||
|
|
||||||
final TableReference lhsTableReference = lhs.resolveTableReference( navigablePath, identifyingColumnsTableExpression );
|
|
||||||
|
|
||||||
lazyTableGroup.setTableGroupInitializerCallback(
|
lazyTableGroup.setTableGroupInitializerCallback(
|
||||||
tableGroup -> tableGroupJoin.applyPredicate(
|
tableGroup -> predicateConsumer.accept(
|
||||||
foreignKeyDescriptor.generateJoinPredicate(
|
foreignKeyDescriptor.generateJoinPredicate(
|
||||||
lhsTableReference,
|
sideNature == ForeignKeyDescriptor.Nature.TARGET ? lhsTableReference : tableGroup.getPrimaryTableReference(),
|
||||||
tableGroup.getPrimaryTableReference(),
|
sideNature == ForeignKeyDescriptor.Nature.TARGET ? tableGroup.getPrimaryTableReference() : lhsTableReference,
|
||||||
sqlAstJoinType,
|
sqlAstJoinType,
|
||||||
sqlExpressionResolver,
|
sqlExpressionResolver,
|
||||||
creationContext
|
creationContext
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
lhs.addTableGroupJoin( tableGroupJoin );
|
|
||||||
|
|
||||||
if ( sqlAstJoinType == SqlAstJoinType.INNER && isNullable ) {
|
if ( sqlAstJoinType == SqlAstJoinType.INNER && isNullable ) {
|
||||||
// Force initialization of the underlying table group join to retain cardinality
|
// Force initialization of the underlying table group join to retain cardinality
|
||||||
lazyTableGroup.getPrimaryTableReference();
|
lazyTableGroup.getPrimaryTableReference();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return tableGroupJoin;
|
return lazyTableGroup;
|
||||||
}
|
}
|
||||||
|
|
||||||
private SqlAstJoinType getJoinType(NavigablePath navigablePath, TableGroup tableGroup) {
|
private SqlAstJoinType getJoinType(NavigablePath navigablePath, TableGroup tableGroup) {
|
||||||
|
@ -21,10 +21,10 @@
|
|||||||
* @author Steve Ebersole
|
* @author Steve Ebersole
|
||||||
*/
|
*/
|
||||||
public class QualifiedJoinPredicatePathConsumer extends BasicDotIdentifierConsumer {
|
public class QualifiedJoinPredicatePathConsumer extends BasicDotIdentifierConsumer {
|
||||||
private final SqmQualifiedJoin sqmJoin;
|
private final SqmQualifiedJoin<?, ?> sqmJoin;
|
||||||
|
|
||||||
public QualifiedJoinPredicatePathConsumer(
|
public QualifiedJoinPredicatePathConsumer(
|
||||||
SqmQualifiedJoin sqmJoin,
|
SqmQualifiedJoin<?, ?> sqmJoin,
|
||||||
SqmCreationState creationState) {
|
SqmCreationState creationState) {
|
||||||
super( creationState );
|
super( creationState );
|
||||||
this.sqmJoin = sqmJoin;
|
this.sqmJoin = sqmJoin;
|
||||||
|
@ -1683,6 +1683,7 @@ protected void consumeQualifiedJoin(HqlParser.QualifiedJoinContext parserJoin, S
|
|||||||
// not consumed by the identifierConsumer
|
// not consumed by the identifierConsumer
|
||||||
join.setExplicitAlias( alias );
|
join.setExplicitAlias( alias );
|
||||||
|
|
||||||
|
final HqlParser.QualifiedJoinPredicateContext qualifiedJoinPredicateContext = parserJoin.qualifiedJoinPredicate();
|
||||||
if ( join instanceof SqmEntityJoin ) {
|
if ( join instanceof SqmEntityJoin ) {
|
||||||
//noinspection unchecked
|
//noinspection unchecked
|
||||||
sqmRoot.addSqmJoin( join );
|
sqmRoot.addSqmJoin( join );
|
||||||
@ -1690,8 +1691,7 @@ protected void consumeQualifiedJoin(HqlParser.QualifiedJoinContext parserJoin, S
|
|||||||
else {
|
else {
|
||||||
if ( getCreationOptions().useStrictJpaCompliance() ) {
|
if ( getCreationOptions().useStrictJpaCompliance() ) {
|
||||||
if ( join.getExplicitAlias() != null ) {
|
if ( join.getExplicitAlias() != null ) {
|
||||||
//noinspection rawtypes
|
if ( ( (SqmAttributeJoin<?, ?>) join ).isFetched() ) {
|
||||||
if ( ( (SqmAttributeJoin) join ).isFetched() ) {
|
|
||||||
throw new StrictJpaComplianceViolation(
|
throw new StrictJpaComplianceViolation(
|
||||||
"Encountered aliased fetch join, but strict JPQL compliance was requested",
|
"Encountered aliased fetch join, but strict JPQL compliance was requested",
|
||||||
StrictJpaComplianceViolation.Type.ALIASED_FETCH_JOIN
|
StrictJpaComplianceViolation.Type.ALIASED_FETCH_JOIN
|
||||||
@ -1699,9 +1699,11 @@ protected void consumeQualifiedJoin(HqlParser.QualifiedJoinContext parserJoin, S
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if ( qualifiedJoinPredicateContext != null && ( (SqmAttributeJoin<?, ?>) join ).isFetched() ) {
|
||||||
|
throw new SemanticException( "with-clause not allowed on fetched associations; use filters" );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
final HqlParser.QualifiedJoinPredicateContext qualifiedJoinPredicateContext = parserJoin.qualifiedJoinPredicate();
|
|
||||||
if ( qualifiedJoinPredicateContext != null ) {
|
if ( qualifiedJoinPredicateContext != null ) {
|
||||||
dotIdentifierConsumerStack.push( new QualifiedJoinPredicatePathConsumer( join, this ) );
|
dotIdentifierConsumerStack.push( new QualifiedJoinPredicatePathConsumer( join, this ) );
|
||||||
try {
|
try {
|
||||||
|
@ -43,6 +43,11 @@ public TableGroup findByAlias(String alias) {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public TableGroup findTableGroupOnLeaf(NavigablePath navigablePath) {
|
||||||
|
return findTableGroup( navigablePath );
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public TableGroup findTableGroup(NavigablePath navigablePath) {
|
public TableGroup findTableGroup(NavigablePath navigablePath) {
|
||||||
if ( tableGroupByPath != null ) {
|
if ( tableGroupByPath != null ) {
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -19,6 +19,9 @@
|
|||||||
* @author Steve Ebersole
|
* @author Steve Ebersole
|
||||||
*/
|
*/
|
||||||
public interface FromClauseAccess {
|
public interface FromClauseAccess {
|
||||||
|
|
||||||
|
TableGroup findTableGroupOnLeaf(NavigablePath navigablePath);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Find a TableGroup by the NavigablePath it is registered under. Returns
|
* Find a TableGroup by the NavigablePath it is registered under. Returns
|
||||||
* {@code null} if no TableGroup is registered under that NavigablePath
|
* {@code null} if no TableGroup is registered under that NavigablePath
|
||||||
|
@ -31,6 +31,11 @@ public SimpleFromClauseAccessImpl(FromClauseAccess parent) {
|
|||||||
this.parent = parent;
|
this.parent = parent;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public TableGroup findTableGroupOnLeaf(NavigablePath navigablePath) {
|
||||||
|
return tableGroupMap.get( navigablePath );
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public TableGroup findTableGroup(NavigablePath navigablePath) {
|
public TableGroup findTableGroup(NavigablePath navigablePath) {
|
||||||
final TableGroup tableGroup = tableGroupMap.get( navigablePath );
|
final TableGroup tableGroup = tableGroupMap.get( navigablePath );
|
||||||
|
@ -59,6 +59,10 @@ public LazyTableGroup(
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isInitialized() {
|
||||||
|
return tableGroup != null;
|
||||||
|
}
|
||||||
|
|
||||||
public TableGroup getUnderlyingTableGroup() {
|
public TableGroup getUnderlyingTableGroup() {
|
||||||
return tableGroup;
|
return tableGroup;
|
||||||
}
|
}
|
||||||
|
@ -6,6 +6,8 @@
|
|||||||
*/
|
*/
|
||||||
package org.hibernate.sql.ast.tree.from;
|
package org.hibernate.sql.ast.tree.from;
|
||||||
|
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
import org.hibernate.LockMode;
|
import org.hibernate.LockMode;
|
||||||
import org.hibernate.query.NavigablePath;
|
import org.hibernate.query.NavigablePath;
|
||||||
import org.hibernate.sql.ast.SqlAstJoinType;
|
import org.hibernate.sql.ast.SqlAstJoinType;
|
||||||
@ -13,6 +15,7 @@
|
|||||||
import org.hibernate.sql.ast.spi.SqlAstCreationContext;
|
import org.hibernate.sql.ast.spi.SqlAstCreationContext;
|
||||||
import org.hibernate.sql.ast.spi.SqlAstCreationState;
|
import org.hibernate.sql.ast.spi.SqlAstCreationState;
|
||||||
import org.hibernate.sql.ast.spi.SqlExpressionResolver;
|
import org.hibernate.sql.ast.spi.SqlExpressionResolver;
|
||||||
|
import org.hibernate.sql.ast.tree.predicate.Predicate;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Steve Ebersole
|
* @author Steve Ebersole
|
||||||
@ -55,4 +58,42 @@ TableGroupJoin createTableGroupJoin(
|
|||||||
SqlAliasBaseGenerator aliasBaseGenerator,
|
SqlAliasBaseGenerator aliasBaseGenerator,
|
||||||
SqlExpressionResolver sqlExpressionResolver,
|
SqlExpressionResolver sqlExpressionResolver,
|
||||||
SqlAstCreationContext creationContext);
|
SqlAstCreationContext creationContext);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a TableGroup as defined for this producer
|
||||||
|
*/
|
||||||
|
default TableGroup createRootTableGroupJoin(
|
||||||
|
NavigablePath navigablePath,
|
||||||
|
TableGroup lhs,
|
||||||
|
String explicitSourceAlias,
|
||||||
|
SqlAstJoinType sqlAstJoinType,
|
||||||
|
boolean fetched,
|
||||||
|
Consumer<Predicate> predicateConsumer,
|
||||||
|
SqlAstCreationState creationState) {
|
||||||
|
return createRootTableGroupJoin(
|
||||||
|
navigablePath,
|
||||||
|
lhs,
|
||||||
|
explicitSourceAlias,
|
||||||
|
sqlAstJoinType,
|
||||||
|
fetched,
|
||||||
|
predicateConsumer,
|
||||||
|
creationState.getSqlAliasBaseGenerator(),
|
||||||
|
creationState.getSqlExpressionResolver(),
|
||||||
|
creationState.getCreationContext()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a TableGroupJoin as defined for this producer
|
||||||
|
*/
|
||||||
|
TableGroup createRootTableGroupJoin(
|
||||||
|
NavigablePath navigablePath,
|
||||||
|
TableGroup lhs,
|
||||||
|
String explicitSourceAlias,
|
||||||
|
SqlAstJoinType sqlAstJoinType,
|
||||||
|
boolean fetched,
|
||||||
|
Consumer<Predicate> predicateConsumer,
|
||||||
|
SqlAliasBaseGenerator aliasBaseGenerator,
|
||||||
|
SqlExpressionResolver sqlExpressionResolver,
|
||||||
|
SqlAstCreationContext creationContext);
|
||||||
}
|
}
|
||||||
|
@ -10,7 +10,10 @@
|
|||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.hibernate.HibernateException;
|
||||||
|
import org.hibernate.QueryException;
|
||||||
import org.hibernate.dialect.DerbyDialect;
|
import org.hibernate.dialect.DerbyDialect;
|
||||||
|
import org.hibernate.dialect.TiDBDialect;
|
||||||
import org.hibernate.query.Query;
|
import org.hibernate.query.Query;
|
||||||
|
|
||||||
import org.hibernate.testing.TestForIssue;
|
import org.hibernate.testing.TestForIssue;
|
||||||
@ -25,9 +28,11 @@
|
|||||||
import org.junit.jupiter.api.BeforeEach;
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import static org.hibernate.testing.orm.junit.ExtraAssertions.assertTyping;
|
||||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||||
|
import static org.junit.jupiter.api.Assertions.fail;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Implementation of WithClauseTest.
|
* Implementation of WithClauseTest.
|
||||||
@ -54,6 +59,26 @@ public void dropTestData(SessionFactoryScope scope) {
|
|||||||
data.cleanup( scope );
|
data.cleanup( scope );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testWithClauseFailsWithFetch(SessionFactoryScope scope) {
|
||||||
|
scope.inTransaction(
|
||||||
|
(session) -> {
|
||||||
|
try {
|
||||||
|
session.createQuery( "from Animal a inner join fetch a.offspring as o with o.bodyWeight = :someLimit" )
|
||||||
|
.setParameter( "someLimit", 1 )
|
||||||
|
.list();
|
||||||
|
fail( "ad-hoc on clause allowed with fetched association" );
|
||||||
|
}
|
||||||
|
catch (IllegalArgumentException e) {
|
||||||
|
assertTyping( QueryException.class, e.getCause() );
|
||||||
|
}
|
||||||
|
catch ( HibernateException e ) {
|
||||||
|
// the expected response...
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testWithClause(SessionFactoryScope scope) {
|
public void testWithClause(SessionFactoryScope scope) {
|
||||||
scope.inTransaction(
|
scope.inTransaction(
|
||||||
@ -85,7 +110,16 @@ public void testWithClause(SessionFactoryScope scope) {
|
|||||||
.list();
|
.list();
|
||||||
assertTrue( list.isEmpty(), "ad-hoc on did not take effect" );
|
assertTrue( list.isEmpty(), "ad-hoc on did not take effect" );
|
||||||
|
|
||||||
list = session.createQuery( "from Human h inner join h.offspring o with o.mother.father = :cousin" )
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@SkipForDialect(dialectClass = TiDBDialect.class, reason = "TiDB db does not support subqueries for ON condition")
|
||||||
|
public void testWithClauseWithImplicitJoin(SessionFactoryScope scope) {
|
||||||
|
scope.inTransaction(
|
||||||
|
(session) -> {
|
||||||
|
List list = session.createQuery( "from Human h inner join h.offspring o with o.mother.father = :cousin" )
|
||||||
.setParameter( "cousin", session.load( Human.class, Long.valueOf( "123" ) ) )
|
.setParameter( "cousin", session.load( Human.class, Long.valueOf( "123" ) ) )
|
||||||
.list();
|
.list();
|
||||||
assertTrue( list.isEmpty(), "ad-hoc did take effect" );
|
assertTrue( list.isEmpty(), "ad-hoc did take effect" );
|
||||||
|
@ -187,7 +187,7 @@ public void testCriteriaParameters() throws Exception {
|
|||||||
1,
|
1,
|
||||||
sqlStatementInterceptor.getSqlQueries().size()
|
sqlStatementInterceptor.getSqlQueries().size()
|
||||||
);
|
);
|
||||||
sqlStatementInterceptor.assertExecuted( "select a1_0.name from Book b1_0 join Author a1_0 on a1_0.book_id=b1_0.id where b1_0.name=? and a1_0.index_id=?" );
|
sqlStatementInterceptor.assertExecuted( "select a1_0.name from Book b1_0 join Author a1_0 on b1_0.id=a1_0.book_id where b1_0.name=? and a1_0.index_id=?" );
|
||||||
} );
|
} );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user