Fix wrong creation of inner join

This commit is contained in:
Andrea Boriero 2021-06-24 12:25:51 +02:00
parent 09266c7ae1
commit bce2737c44
11 changed files with 96 additions and 34 deletions

View File

@ -808,6 +808,9 @@ public class ToOneAttributeMapping
return SqlAstJoinType.LEFT;
}
else {
if ( parentTableGroup.isOuterJoined() ) {
return SqlAstJoinType.LEFT;
}
return SqlAstJoinType.INNER;
}
}

View File

@ -13,6 +13,7 @@ import java.util.function.Consumer;
import org.hibernate.metamodel.mapping.ModelPartContainer;
import org.hibernate.query.NavigablePath;
import org.hibernate.sql.ast.SqlAstJoinType;
import org.hibernate.sql.ast.tree.from.TableGroup;
import org.hibernate.sql.ast.tree.from.TableGroupJoin;
import org.hibernate.sql.ast.tree.from.TableReference;
@ -32,7 +33,7 @@ public class TableGroupImpl implements TableGroup {
private final ModelPartContainer container;
private final String sourceAlias;
private boolean isOuterJoined;
public TableGroupImpl(
NavigablePath navigablePath,
@ -77,6 +78,11 @@ public class TableGroupImpl implements TableGroup {
return tableGroupJoins == null ? Collections.emptyList() : Collections.unmodifiableList( tableGroupJoins );
}
@Override
public boolean isOuterJoined() {
return isOuterJoined;
}
@Override
public boolean hasTableGroupJoins() {
return tableGroupJoins != null && !tableGroupJoins.isEmpty();
@ -87,6 +93,9 @@ public class TableGroupImpl implements TableGroup {
if ( tableGroupJoins == null ) {
tableGroupJoins = new ArrayList<>();
}
if ( join.getJoinType() != SqlAstJoinType.INNER ) {
isOuterJoined = true;
}
if ( !tableGroupJoins.contains( join ) ) {
tableGroupJoins.add( join );
}

View File

@ -60,6 +60,11 @@ public class CteTableGroup implements TableGroup {
return Collections.emptyList();
}
@Override
public boolean isOuterJoined() {
return false;
}
@Override
public TableReference getTableReference(NavigablePath navigablePath, String tableExpression) {
if ( cteTableReference.getTableExpression().equals( tableExpression ) ) {

View File

@ -11,10 +11,10 @@ import java.util.Collections;
import java.util.List;
import java.util.function.Consumer;
import org.hibernate.LockMode;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.metamodel.mapping.ModelPart;
import org.hibernate.query.NavigablePath;
import org.hibernate.sql.ast.SqlAstJoinType;
import org.hibernate.sql.ast.spi.SqlAliasBase;
/**
@ -28,6 +28,7 @@ public abstract class AbstractTableGroup extends AbstractColumnReferenceQualifie
private List<TableGroupJoin> tableGroupJoins;
private boolean isInnerJoinPossible;
private boolean isOuterJoined;
private final SessionFactoryImplementor sessionFactory;
@ -97,6 +98,11 @@ public abstract class AbstractTableGroup extends AbstractColumnReferenceQualifie
return tableGroupJoins == null ? Collections.emptyList() : Collections.unmodifiableList( tableGroupJoins );
}
@Override
public boolean isOuterJoined() {
return isOuterJoined;
}
@Override
public boolean hasTableGroupJoins() {
return tableGroupJoins != null && !tableGroupJoins.isEmpty();
@ -107,6 +113,9 @@ public abstract class AbstractTableGroup extends AbstractColumnReferenceQualifie
if ( tableGroupJoins == null ) {
tableGroupJoins = new ArrayList<>();
}
if ( join.getJoinType() != SqlAstJoinType.INNER ) {
isOuterJoined = true;
}
if ( !tableGroupJoins.contains( join ) ) {
tableGroupJoins.add( join );
}

View File

@ -11,9 +11,9 @@ import java.util.Collections;
import java.util.List;
import java.util.function.Consumer;
import org.hibernate.LockMode;
import org.hibernate.metamodel.mapping.EmbeddableValuedModelPart;
import org.hibernate.query.NavigablePath;
import org.hibernate.sql.ast.SqlAstJoinType;
/**
* @author Steve Ebersole
@ -25,6 +25,7 @@ public class CompositeTableGroup implements VirtualTableGroup {
private final TableGroup underlyingTableGroup;
private List<TableGroupJoin> tableGroupJoins;
private boolean isOuterJoined;
public CompositeTableGroup(
NavigablePath navigablePath,
@ -66,6 +67,11 @@ public class CompositeTableGroup implements VirtualTableGroup {
return tableGroupJoins == null ? Collections.emptyList() : Collections.unmodifiableList( tableGroupJoins );
}
@Override
public boolean isOuterJoined() {
return isOuterJoined;
}
@Override
public boolean hasTableGroupJoins() {
return tableGroupJoins != null && !tableGroupJoins.isEmpty();
@ -76,6 +82,9 @@ public class CompositeTableGroup implements VirtualTableGroup {
if ( tableGroupJoins == null ) {
tableGroupJoins = new ArrayList<>();
}
if ( join.getJoinType() != SqlAstJoinType.INNER ) {
isOuterJoined = true;
}
if ( !tableGroupJoins.contains( join ) ) {
tableGroupJoins.add( join );
}

View File

@ -12,7 +12,6 @@ import java.util.function.Consumer;
import java.util.function.Predicate;
import java.util.function.Supplier;
import org.hibernate.LockMode;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.metamodel.mapping.ModelPart;
import org.hibernate.query.NavigablePath;
@ -112,6 +111,14 @@ public class LazyTableGroup extends AbstractColumnReferenceQualifier implements
}
}
@Override
public boolean isOuterJoined() {
if ( tableGroup != null ) {
return parentTableGroup.isOuterJoined() || tableGroup.isOuterJoined();
}
return parentTableGroup.isOuterJoined();
}
@Override
public NavigablePath getNavigablePath() {
return navigablePath;

View File

@ -87,6 +87,11 @@ public class MutatingTableReferenceGroupWrapper implements VirtualTableGroup {
return Collections.emptyList();
}
@Override
public boolean isOuterJoined() {
return false;
}
@Override
public boolean hasTableGroupJoins() {
return false;

View File

@ -42,6 +42,8 @@ public interface TableGroup extends SqlAstNode, ColumnReferenceQualifier, SqmPat
List<TableGroupJoin> getTableGroupJoins();
boolean isOuterJoined();
boolean hasTableGroupJoins();
void addTableGroupJoin(TableGroupJoin join);

View File

@ -11,11 +11,11 @@ import java.util.Collections;
import java.util.List;
import java.util.function.Consumer;
import org.hibernate.LockMode;
import org.hibernate.metamodel.mapping.ModelPart;
import org.hibernate.metamodel.mapping.ModelPartContainer;
import org.hibernate.persister.entity.UnionSubclassEntityPersister;
import org.hibernate.query.NavigablePath;
import org.hibernate.sql.ast.SqlAstJoinType;
/**
* @author Andrea Boriero
@ -27,6 +27,7 @@ public class UnionTableGroup implements VirtualTableGroup {
private final UnionSubclassEntityPersister modelPart;
private final String sourceAlias;
private final TableReference tableReference;
private boolean isOuterJoined;
public UnionTableGroup(
NavigablePath navigablePath,
@ -74,11 +75,19 @@ public class UnionTableGroup implements VirtualTableGroup {
return tableGroupJoins != null && !tableGroupJoins.isEmpty();
}
@Override
public boolean isOuterJoined() {
return isOuterJoined;
}
@Override
public void addTableGroupJoin(TableGroupJoin join) {
if ( tableGroupJoins == null ) {
tableGroupJoins = new ArrayList<>();
}
if ( join.getJoinType() != SqlAstJoinType.INNER ) {
isOuterJoined = true;
}
if ( !tableGroupJoins.contains( join ) ) {
tableGroupJoins.add( join );
}

View File

@ -9,7 +9,6 @@ package org.hibernate.sql.results.graph.collection.internal;
import java.util.List;
import java.util.function.Consumer;
import org.hibernate.LockMode;
import org.hibernate.metamodel.mapping.ModelPart;
import org.hibernate.metamodel.mapping.internal.EntityCollectionPart;
import org.hibernate.query.NavigablePath;
@ -66,6 +65,11 @@ public class EntityCollectionPartTableGroup implements TableGroup {
return collectionTableGroup.getTableGroupJoins();
}
@Override
public boolean isOuterJoined() {
return collectionTableGroup.isOuterJoined();
}
@Override
public boolean hasTableGroupJoins() {
return collectionTableGroup.hasTableGroupJoins();

View File

@ -120,20 +120,20 @@ public class OuterJoinTest extends BaseCoreFunctionalTestCase {
em.merge(association);
em.merge(new A(1L, "a", association));
// em.merge(new A(2L, "b", association));
// em.merge(new A(3L, "c", association));
//
// em.merge(new B(1L, "d", association));
// em.merge(new B(2L, "e", association));
// em.merge(new B(3L, "f", association));
//
// em.merge(new C(1L, "g", association));
// em.merge(new C(2L, "h", association));
// em.merge(new C(4L, "j", association));
//
// em.merge(new D(1L, "k", association));
// em.merge(new D(2L, "l", association));
// em.merge(new D(4L, "m", association));
em.merge(new A(2L, "b", association));
em.merge(new A(3L, "c", association));
em.merge(new B(1L, "d", association));
em.merge(new B(2L, "e", association));
em.merge(new B(3L, "f", association));
em.merge(new C(1L, "g", association));
em.merge(new C(2L, "h", association));
em.merge(new C(4L, "j", association));
em.merge(new D(1L, "k", association));
em.merge(new D(2L, "l", association));
em.merge(new D(4L, "m", association));
});
}
@ -144,20 +144,20 @@ public class OuterJoinTest extends BaseCoreFunctionalTestCase {
em.merge(association);
em.merge(new A(1L, "a", association));
// em.merge(new A(2L, "b", association));
// em.merge(new A(3L, "c", association));
//
// em.merge(new B(1L, "d", association));
// em.merge(new B(2L, "e", association));
// em.merge(new B(3L, "f", association));
//
// em.merge(new C(1L, "g", association));
// em.merge(new C(2L, "h", association));
// em.merge(new C(4L, "j", association));
//
// em.merge(new D(1L, "k", association));
// em.merge(new D(2L, "l", association));
// em.merge(new D(4L, "m", association));
em.merge(new A(2L, "b", association));
em.merge(new A(3L, "c", association));
em.merge(new B(1L, "d", association));
em.merge(new B(2L, "e", association));
em.merge(new B(3L, "f", association));
em.merge(new C(1L, "g", association));
em.merge(new C(2L, "h", association));
em.merge(new C(4L, "j", association));
em.merge(new D(1L, "k", association));
em.merge(new D(2L, "l", association));
em.merge(new D(4L, "m", association));
});
}