Fix wrong creation of inner join
This commit is contained in:
parent
bf22f098d1
commit
94a258c8d7
|
@ -50,7 +50,7 @@ public class InformixSqmToSqlAstConverter<T extends Statement> extends BaseSqmTo
|
|||
if ( this.needsDummyTableGroup ) {
|
||||
querySpec.getFromClause().addRoot(
|
||||
new StandardTableGroup(
|
||||
false,
|
||||
true,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
|
|
|
@ -50,7 +50,7 @@ public class IngresSqmToSqlAstConverter<T extends Statement> extends BaseSqmToSq
|
|||
if ( this.needsDummyTableGroup ) {
|
||||
querySpec.getFromClause().addRoot(
|
||||
new StandardTableGroup(
|
||||
false,
|
||||
true,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
|
|
|
@ -147,7 +147,6 @@ class DatabaseSnapshotExecutor {
|
|||
if ( contributorMapping instanceof EntityAssociationMapping ) {
|
||||
domainResults.add(
|
||||
( (EntityAssociationMapping) contributorMapping ).createDelayedDomainResult(
|
||||
true,
|
||||
navigablePath,
|
||||
rootTableGroup,
|
||||
null,
|
||||
|
|
|
@ -41,7 +41,6 @@ public interface EntityAssociationMapping extends ModelPart, Association, TableG
|
|||
* Create a delayed DomainResult for a specific reference to this ModelPart.
|
||||
*/
|
||||
default <T> DomainResult<T> createDelayedDomainResult(
|
||||
boolean canUseInnerJoins,
|
||||
NavigablePath navigablePath,
|
||||
TableGroup tableGroup,
|
||||
String resultVariable,
|
||||
|
|
|
@ -84,6 +84,11 @@ public class EntityCollectionPart
|
|||
}
|
||||
|
||||
|
||||
@Override
|
||||
public SqlAstJoinType getDefaultSqlAstJoinType(TableGroup parentTableGroup) {
|
||||
return SqlAstJoinType.INNER;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Nature getNature() {
|
||||
return nature;
|
||||
|
|
|
@ -556,6 +556,11 @@ public class PluralAttributeMappingImpl
|
|||
return sqlAliasStem;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SqlAstJoinType getDefaultSqlAstJoinType(TableGroup parentTableGroup) {
|
||||
return SqlAstJoinType.LEFT;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TableGroupJoin createTableGroupJoin(
|
||||
NavigablePath navigablePath,
|
||||
|
@ -608,7 +613,7 @@ public class PluralAttributeMappingImpl
|
|||
SqlExpressionResolver sqlExpressionResolver,
|
||||
SqlAstCreationContext creationContext) {
|
||||
final TableGroup tableGroup = createOneToManyTableGroup(
|
||||
lhs.canUseInnerJoins(),
|
||||
lhs.canUseInnerJoins() && sqlAstJoinType == SqlAstJoinType.INNER,
|
||||
navigablePath,
|
||||
fetched,
|
||||
explicitSourceAlias,
|
||||
|
@ -777,7 +782,7 @@ public class PluralAttributeMappingImpl
|
|||
SqlExpressionResolver sqlExpressionResolver,
|
||||
SqlAstCreationContext creationContext) {
|
||||
final TableGroup tableGroup = createCollectionTableGroup(
|
||||
lhs.canUseInnerJoins(),
|
||||
lhs.canUseInnerJoins() && sqlAstJoinType == SqlAstJoinType.INNER,
|
||||
navigablePath,
|
||||
fetched,
|
||||
explicitSourceAlias,
|
||||
|
|
|
@ -750,7 +750,6 @@ public class ToOneAttributeMapping
|
|||
|
||||
@Override
|
||||
public <T> DomainResult<T> createDelayedDomainResult(
|
||||
boolean canUseInnerJoins,
|
||||
NavigablePath navigablePath,
|
||||
TableGroup tableGroup,
|
||||
String resultVariable,
|
||||
|
@ -762,7 +761,7 @@ public class ToOneAttributeMapping
|
|||
navigablePath,
|
||||
tableGroup,
|
||||
null,
|
||||
SqlAstJoinType.LEFT,
|
||||
getDefaultSqlAstJoinType( tableGroup ),
|
||||
true,
|
||||
creationState.getSqlAstCreationState()
|
||||
);
|
||||
|
@ -807,7 +806,7 @@ public class ToOneAttributeMapping
|
|||
);
|
||||
}
|
||||
|
||||
private SqlAstJoinType getDefaultSqlAstJoinType(TableGroup parentTableGroup) {
|
||||
public SqlAstJoinType getDefaultSqlAstJoinType(TableGroup parentTableGroup) {
|
||||
if ( isNullable ) {
|
||||
return SqlAstJoinType.LEFT;
|
||||
}
|
||||
|
@ -857,7 +856,7 @@ public class ToOneAttributeMapping
|
|||
SqlExpressionResolver sqlExpressionResolver,
|
||||
SqlAstCreationContext creationContext) {
|
||||
final SqlAliasBase sqlAliasBase = aliasBaseGenerator.createSqlAliasBase( sqlAliasStem );
|
||||
boolean canUseInnerJoin = lhs.canUseInnerJoins() && sqlAstJoinType == SqlAstJoinType.INNER;
|
||||
boolean canUseInnerJoin = sqlAstJoinType == SqlAstJoinType.INNER || lhs.canUseInnerJoins() && !isNullable;
|
||||
final LazyTableGroup lazyTableGroup = new LazyTableGroup(
|
||||
canUseInnerJoin,
|
||||
navigablePath,
|
||||
|
|
|
@ -414,8 +414,8 @@ public class DomainResultCreationStateImpl
|
|||
}
|
||||
}
|
||||
|
||||
fetchableContainer.visitKeyFetchables( fetchableConsumer, null );
|
||||
fetchableContainer.visitFetchables( fetchableConsumer, null );
|
||||
|
||||
return fetches;
|
||||
}
|
||||
|
||||
|
|
|
@ -79,6 +79,7 @@ public class CompleteResultBuilderEntityJpa implements CompleteResultBuilderEnti
|
|||
impl.getFromClauseAccess().resolveTableGroup(
|
||||
navigablePath,
|
||||
np -> entityDescriptor.createRootTableGroup(
|
||||
// since this is only used for result set mappings, the canUseInnerJoins value is irrelevant.
|
||||
true,
|
||||
navigablePath,
|
||||
null,
|
||||
|
|
|
@ -71,6 +71,7 @@ public class CompleteResultBuilderEntityStandard implements CompleteResultBuilde
|
|||
impl.getFromClauseAccess().resolveTableGroup(
|
||||
navigablePath,
|
||||
np -> entityDescriptor.createRootTableGroup(
|
||||
// since this is only used for result set mappings, the canUseInnerJoins value is irrelevant.
|
||||
true,
|
||||
navigablePath,
|
||||
null,
|
||||
|
|
|
@ -57,6 +57,7 @@ public class ImplicitModelPartResultBuilderEntity
|
|||
}
|
||||
|
||||
return modelPart.getEntityMappingType().createRootTableGroup(
|
||||
// since this is only used for result set mappings, the canUseInnerJoins value is irrelevant.
|
||||
true,
|
||||
navigablePath,
|
||||
null,
|
||||
|
|
|
@ -11,7 +11,6 @@ import java.util.Collection;
|
|||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
|
|
@ -1835,7 +1835,6 @@ public abstract class BaseSqmToSqlAstConverter<T extends Statement> extends Base
|
|||
// If we have just inner joins against a correlated root, we can render the joins as references
|
||||
final SqlAliasBase sqlAliasBase = sqlAliasBaseManager.createSqlAliasBase( parentTableGroup.getGroupAlias() );
|
||||
tableGroup = new CorrelatedTableGroup(
|
||||
parentTableGroup.canUseInnerJoins(),
|
||||
parentTableGroup,
|
||||
sqlAliasBase,
|
||||
currentQuerySpec(),
|
||||
|
@ -2101,8 +2100,9 @@ public abstract class BaseSqmToSqlAstConverter<T extends Statement> extends Base
|
|||
private void consumeEntityJoin(SqmEntityJoin sqmJoin, TableGroup lhsTableGroup) {
|
||||
final EntityPersister entityDescriptor = resolveEntityPersister( sqmJoin.getReferencedPathSource() );
|
||||
|
||||
final SqlAstJoinType correspondingSqlJoinType = sqmJoin.getSqmJoinType().getCorrespondingSqlJoinType();
|
||||
final TableGroup tableGroup = entityDescriptor.createRootTableGroup(
|
||||
true,
|
||||
correspondingSqlJoinType == SqlAstJoinType.INNER || correspondingSqlJoinType == SqlAstJoinType.CROSS ,
|
||||
sqmJoin.getNavigablePath(),
|
||||
sqmJoin.getExplicitAlias(),
|
||||
() -> predicate -> additionalRestrictions = SqlAstTreeHelper.combinePredicates(
|
||||
|
@ -2116,7 +2116,7 @@ public abstract class BaseSqmToSqlAstConverter<T extends Statement> extends Base
|
|||
|
||||
final TableGroupJoin tableGroupJoin = new TableGroupJoin(
|
||||
sqmJoin.getNavigablePath(),
|
||||
sqmJoin.getSqmJoinType().getCorrespondingSqlJoinType(),
|
||||
correspondingSqlJoinType,
|
||||
tableGroup,
|
||||
null
|
||||
);
|
||||
|
@ -2125,7 +2125,7 @@ public abstract class BaseSqmToSqlAstConverter<T extends Statement> extends Base
|
|||
consumeExplicitJoins( sqmJoin, tableGroupJoin.getJoinedGroup() );
|
||||
consumeReusablePaths( sqmJoin, tableGroupJoin.getJoinedGroup() );
|
||||
|
||||
// add any additional join restrictions
|
||||
// add any additional join restrictionsHbmResultSetMappingDescriptor.java
|
||||
if ( sqmJoin.getJoinPredicate() != null ) {
|
||||
tableGroupJoin.applyPredicate(
|
||||
(Predicate) sqmJoin.getJoinPredicate().accept( this )
|
||||
|
@ -2169,11 +2169,13 @@ public abstract class BaseSqmToSqlAstConverter<T extends Statement> extends Base
|
|||
if ( subPart instanceof TableGroupJoinProducer ) {
|
||||
implicitJoinChecker.accept( joinedPath );
|
||||
final TableGroupJoinProducer joinProducer = (TableGroupJoinProducer) subPart;
|
||||
final SqlAstJoinType defaultSqlAstJoinType = joinProducer.getDefaultSqlAstJoinType(
|
||||
parentTableGroup );
|
||||
final TableGroupJoin tableGroupJoin = joinProducer.createTableGroupJoin(
|
||||
joinedPath.getNavigablePath(),
|
||||
parentTableGroup,
|
||||
null,
|
||||
SqlAstJoinType.LEFT,
|
||||
defaultSqlAstJoinType,
|
||||
false,
|
||||
this
|
||||
);
|
||||
|
@ -4281,7 +4283,6 @@ public abstract class BaseSqmToSqlAstConverter<T extends Statement> extends Base
|
|||
final TableGroup parentTableGroup = parentFromClauseAccess.getTableGroup( parentNavPath );
|
||||
final SqlAliasBase sqlAliasBase = sqlAliasBaseManager.createSqlAliasBase( parentTableGroup.getGroupAlias() );
|
||||
final TableGroup tableGroup = new CorrelatedTableGroup(
|
||||
parentTableGroup.canUseInnerJoins(),
|
||||
parentTableGroup,
|
||||
sqlAliasBase,
|
||||
subQuerySpec,
|
||||
|
@ -4676,6 +4677,7 @@ public abstract class BaseSqmToSqlAstConverter<T extends Statement> extends Base
|
|||
}
|
||||
|
||||
if ( joined && fetchable instanceof TableGroupJoinProducer ) {
|
||||
TableGroupJoinProducer tableGroupJoinProducer = (TableGroupJoinProducer) fetchable;
|
||||
fromClauseIndex.resolveTableGroup(
|
||||
fetchablePath,
|
||||
np -> {
|
||||
|
@ -4685,7 +4687,7 @@ public abstract class BaseSqmToSqlAstConverter<T extends Statement> extends Base
|
|||
fetchablePath,
|
||||
lhs,
|
||||
alias,
|
||||
SqlAstJoinType.LEFT,
|
||||
tableGroupJoinProducer.getDefaultSqlAstJoinType( lhs ),
|
||||
true,
|
||||
this
|
||||
);
|
||||
|
|
|
@ -20,13 +20,13 @@ import org.hibernate.sql.ast.spi.SqlAliasBase;
|
|||
* @author Steve Ebersole
|
||||
*/
|
||||
public abstract class AbstractTableGroup extends AbstractColumnReferenceQualifier implements TableGroup {
|
||||
private final boolean canUseInnerJoins;
|
||||
private final NavigablePath navigablePath;
|
||||
private final TableGroupProducer producer;
|
||||
private final String sourceAlias;
|
||||
private final SqlAliasBase sqlAliasBase;
|
||||
|
||||
private List<TableGroupJoin> tableGroupJoins;
|
||||
private boolean canUseInnerJoins;
|
||||
|
||||
private final SessionFactoryImplementor sessionFactory;
|
||||
|
||||
|
|
|
@ -13,7 +13,6 @@ import java.util.function.Consumer;
|
|||
|
||||
import org.hibernate.metamodel.mapping.EmbeddableValuedModelPart;
|
||||
import org.hibernate.query.NavigablePath;
|
||||
import org.hibernate.sql.ast.SqlAstJoinType;
|
||||
|
||||
/**
|
||||
* @author Steve Ebersole
|
||||
|
@ -25,13 +24,11 @@ public class CompositeTableGroup implements VirtualTableGroup {
|
|||
private final TableGroup underlyingTableGroup;
|
||||
|
||||
private List<TableGroupJoin> tableGroupJoins;
|
||||
private final boolean canUseInnerJoins;
|
||||
|
||||
public CompositeTableGroup(
|
||||
NavigablePath navigablePath,
|
||||
EmbeddableValuedModelPart compositionMapping,
|
||||
TableGroup underlyingTableGroup) {
|
||||
this.canUseInnerJoins = underlyingTableGroup.canUseInnerJoins();
|
||||
this.navigablePath = navigablePath;
|
||||
this.compositionMapping = compositionMapping;
|
||||
this.underlyingTableGroup = underlyingTableGroup;
|
||||
|
@ -70,7 +67,7 @@ public class CompositeTableGroup implements VirtualTableGroup {
|
|||
|
||||
@Override
|
||||
public boolean canUseInnerJoins() {
|
||||
return canUseInnerJoins;
|
||||
return underlyingTableGroup.canUseInnerJoins();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -29,14 +29,13 @@ public class CorrelatedTableGroup extends AbstractTableGroup {
|
|||
private final Consumer<Predicate> joinPredicateConsumer;
|
||||
|
||||
public CorrelatedTableGroup(
|
||||
boolean canUseInnerJoins,
|
||||
TableGroup correlatedTableGroup,
|
||||
SqlAliasBase sqlAliasBase,
|
||||
QuerySpec querySpec,
|
||||
Consumer<Predicate> joinPredicateConsumer,
|
||||
SessionFactoryImplementor sessionFactory) {
|
||||
super(
|
||||
canUseInnerJoins,
|
||||
true,
|
||||
correlatedTableGroup.getNavigablePath(),
|
||||
(TableGroupProducer) correlatedTableGroup.getExpressionType(),
|
||||
null,
|
||||
|
|
|
@ -22,7 +22,7 @@ import org.hibernate.sql.ast.spi.SqlAliasBase;
|
|||
*/
|
||||
public class LazyTableGroup extends AbstractColumnReferenceQualifier implements TableGroup {
|
||||
|
||||
private boolean canUseInnerJoins;
|
||||
private final boolean canUseInnerJoins;
|
||||
private final NavigablePath navigablePath;
|
||||
private final TableGroupProducer producer;
|
||||
private final String sourceAlias;
|
||||
|
|
|
@ -18,6 +18,9 @@ import org.hibernate.sql.ast.spi.SqlExpressionResolver;
|
|||
* @author Steve Ebersole
|
||||
*/
|
||||
public interface TableGroupJoinProducer extends TableGroupProducer {
|
||||
|
||||
SqlAstJoinType getDefaultSqlAstJoinType(TableGroup parentTableGroup);
|
||||
|
||||
/**
|
||||
* Create a TableGroupJoin as defined for this producer
|
||||
*/
|
||||
|
|
|
@ -6,6 +6,8 @@
|
|||
*/
|
||||
package org.hibernate.sql.results.graph.embeddable;
|
||||
|
||||
import org.hibernate.sql.ast.SqlAstJoinType;
|
||||
import org.hibernate.sql.ast.tree.from.TableGroup;
|
||||
import org.hibernate.sql.results.graph.Fetchable;
|
||||
import org.hibernate.metamodel.mapping.EmbeddableValuedModelPart;
|
||||
|
||||
|
@ -13,4 +15,8 @@ import org.hibernate.metamodel.mapping.EmbeddableValuedModelPart;
|
|||
* @author Steve Ebersole
|
||||
*/
|
||||
public interface EmbeddableValuedFetchable extends EmbeddableValuedModelPart, Fetchable {
|
||||
@Override
|
||||
default SqlAstJoinType getDefaultSqlAstJoinType(TableGroup parentTableGroup) {
|
||||
return SqlAstJoinType.LEFT;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,12 +18,14 @@ import org.junit.After;
|
|||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import org.hibernate.Hibernate;
|
||||
import org.hibernate.query.NativeQuery;
|
||||
|
||||
import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
/**
|
||||
* @author Max Rydahl Andersen
|
||||
|
@ -126,6 +128,7 @@ public class WhereTest extends BaseCoreFunctionalTestCase {
|
|||
|
||||
File parent = (File) query.list().get( 0 );
|
||||
// @Where should not be applied
|
||||
assertTrue( Hibernate.isInitialized( parent.getChildren() ) );
|
||||
assertEquals( 2, parent.getChildren().size() );
|
||||
}
|
||||
);
|
||||
|
|
|
@ -18,6 +18,7 @@ import org.hibernate.testing.orm.junit.FailureExpected;
|
|||
import org.hibernate.testing.orm.junit.RequiresDialectFeature;
|
||||
import org.hibernate.testing.orm.junit.SessionFactory;
|
||||
import org.hibernate.testing.orm.junit.SessionFactoryScope;
|
||||
import org.junit.Assert;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
|
@ -245,7 +246,32 @@ public class ExtraLazyTest {
|
|||
session.clear();
|
||||
List results = session.getNamedQuery( "userSessionData" ).setParameter( "uname", "%in" ).list();
|
||||
assertThat( results.size(), is( 2 ) );
|
||||
gavin = (User) ( (Object[]) results.get( 0 ) )[0];
|
||||
gavin = (User) results.get( 0 ) ;
|
||||
assertThat( gavin.getName(), is( "gavin" ) );
|
||||
Assert.assertTrue( Hibernate.isInitialized( gavin.getSession()) );
|
||||
assertThat( gavin.getSession().size(), is( 2 ) );
|
||||
session.createQuery( "delete SessionAttribute" ).executeUpdate();
|
||||
session.createQuery( "delete User" ).executeUpdate();
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
@Test
|
||||
@RequiresDialectFeature(feature = DialectFeatureChecks.DoubleQuoteQuoting.class)
|
||||
public void testSQLQuery2(SessionFactoryScope scope) {
|
||||
scope.inTransaction(
|
||||
session -> {
|
||||
User gavin = new User( "gavin", "secret" );
|
||||
User turin = new User( "turin", "tiger" );
|
||||
gavin.getSession().put( "foo", new SessionAttribute( "foo", "foo bar baz" ) );
|
||||
gavin.getSession().put( "bar", new SessionAttribute( "bar", "foo bar baz 2" ) );
|
||||
session.persist( gavin );
|
||||
session.persist( turin );
|
||||
session.flush();
|
||||
session.clear();
|
||||
List results = session.getNamedQuery( "userData" ).setParameter( "uname", "%in" ).list();
|
||||
assertThat( results.size(), is( 2 ) );
|
||||
gavin = (User) results.get( 0 );
|
||||
assertThat( gavin.getName(), is( "gavin" ) );
|
||||
assertThat( gavin.getSession().size(), is( 2 ) );
|
||||
session.createQuery( "delete SessionAttribute" ).executeUpdate();
|
||||
|
|
Loading…
Reference in New Issue