HHH-16003 Create correct table group for embedded valued paths
This commit is contained in:
parent
2e3a18a3c6
commit
e884ab3082
|
@ -3351,7 +3351,7 @@ public abstract class BaseSqmToSqlAstConverter<T extends Statement> extends Base
|
|||
if ( sqmPath instanceof SqmEntityValuedSimplePath<?>
|
||||
|| sqmPath instanceof SqmEmbeddedValuedSimplePath<?>
|
||||
|| sqmPath instanceof SqmAnyValuedSimplePath<?> ) {
|
||||
final TableGroup existingTableGroup = fromClauseIndex.findTableGroup( sqmPath.getNavigablePath() );
|
||||
final TableGroup existingTableGroup = fromClauseIndex.findTableGroupForGetOrCreate( sqmPath.getNavigablePath() );
|
||||
if ( existingTableGroup == null ) {
|
||||
final TableGroup createdTableGroup = createTableGroup(
|
||||
fromClauseIndex.getTableGroup( sqmPath.getLhs().getNavigablePath() ),
|
||||
|
@ -3387,7 +3387,7 @@ public abstract class BaseSqmToSqlAstConverter<T extends Statement> extends Base
|
|||
if ( parentPath == null ) {
|
||||
return null;
|
||||
}
|
||||
final TableGroup tableGroup = fromClauseIndex.findTableGroup( parentPath.getNavigablePath() );
|
||||
final TableGroup tableGroup = fromClauseIndex.findTableGroupForGetOrCreate( parentPath.getNavigablePath() );
|
||||
if ( tableGroup == null ) {
|
||||
final TableGroup parentTableGroup = prepareReusablePath(
|
||||
fromClauseIndex,
|
||||
|
@ -3454,7 +3454,7 @@ public abstract class BaseSqmToSqlAstConverter<T extends Statement> extends Base
|
|||
path = selectionPath;
|
||||
}
|
||||
final FromClauseIndex fromClauseIndex = getFromClauseIndex();
|
||||
final TableGroup tableGroup = fromClauseIndex.findTableGroup( path.getNavigablePath() );
|
||||
final TableGroup tableGroup = fromClauseIndex.findTableGroupForGetOrCreate( path.getNavigablePath() );
|
||||
if ( tableGroup == null ) {
|
||||
prepareReusablePath( path, () -> null );
|
||||
|
||||
|
|
|
@ -33,6 +33,15 @@ public interface FromClauseAccess {
|
|||
*/
|
||||
TableGroup findTableGroup(NavigablePath navigablePath);
|
||||
|
||||
/**
|
||||
* Find the TableGroup by the NavigablePath for the purpose of creating a
|
||||
* new TableGroup if none can be found. Returns {@code null} if no TableGroup
|
||||
* or parent table group is registered under that NavigablePath
|
||||
*/
|
||||
default TableGroup findTableGroupForGetOrCreate(NavigablePath navigablePath) {
|
||||
return findTableGroup( navigablePath );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a TableGroup by the NavigablePath it is registered under. If there is
|
||||
* no registration, an exception is thrown.
|
||||
|
@ -62,7 +71,7 @@ public interface FromClauseAccess {
|
|||
* @see #registerTableGroup
|
||||
*/
|
||||
default TableGroup resolveTableGroup(NavigablePath navigablePath, Function<NavigablePath, TableGroup> creator) {
|
||||
TableGroup tableGroup = findTableGroup( navigablePath );
|
||||
TableGroup tableGroup = findTableGroupForGetOrCreate( navigablePath );
|
||||
if ( tableGroup == null ) {
|
||||
tableGroup = creator.apply( navigablePath );
|
||||
registerTableGroup( navigablePath, tableGroup );
|
||||
|
|
|
@ -9,9 +9,12 @@ package org.hibernate.sql.ast.spi;
|
|||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.hibernate.metamodel.mapping.EmbeddableValuedModelPart;
|
||||
import org.hibernate.metamodel.model.domain.NavigableRole;
|
||||
import org.hibernate.spi.NavigablePath;
|
||||
import org.hibernate.sql.ast.SqlTreeCreationLogger;
|
||||
import org.hibernate.sql.ast.tree.from.TableGroup;
|
||||
import org.hibernate.sql.ast.tree.from.VirtualTableGroup;
|
||||
|
||||
import org.jboss.logging.Logger;
|
||||
|
||||
|
@ -47,6 +50,39 @@ public class SimpleFromClauseAccessImpl implements FromClauseAccess {
|
|||
return parent.findTableGroup( navigablePath );
|
||||
}
|
||||
|
||||
@Override
|
||||
public TableGroup findTableGroupForGetOrCreate(NavigablePath navigablePath) {
|
||||
final TableGroup tableGroup = findTableGroup( navigablePath );
|
||||
if ( parent != null && tableGroup instanceof VirtualTableGroup && tableGroup.getModelPart() instanceof EmbeddableValuedModelPart ) {
|
||||
final NavigableRole navigableRole = tableGroup.getModelPart().getNavigableRole();
|
||||
if ( navigableRole != null ) {
|
||||
// Traverse up the navigable path to the point where resolving the path leads us to a regular TableGroup
|
||||
NavigableRole parentRole = navigableRole.getParent();
|
||||
NavigablePath parentPath = navigablePath.getParent();
|
||||
while ( parentRole.getParent() != null ) {
|
||||
parentRole = parentRole.getParent();
|
||||
parentPath = parentPath.getParent();
|
||||
}
|
||||
// Only return the TableGroup if its regular parent TableGroup corresponds to the underlying one
|
||||
if ( findTableGroup( parentPath ) == getUnderlyingTableGroup( (VirtualTableGroup) tableGroup ) ) {
|
||||
return tableGroup;
|
||||
}
|
||||
else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
return tableGroup;
|
||||
}
|
||||
|
||||
private TableGroup getUnderlyingTableGroup(VirtualTableGroup virtualTableGroup) {
|
||||
final TableGroup tableGroup = virtualTableGroup.getUnderlyingTableGroup();
|
||||
if ( tableGroup instanceof VirtualTableGroup ) {
|
||||
return getUnderlyingTableGroup( (VirtualTableGroup) tableGroup );
|
||||
}
|
||||
return tableGroup;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void registerTableGroup(NavigablePath navigablePath, TableGroup tableGroup) {
|
||||
final Logger logger = SqlTreeCreationLogger.LOGGER;
|
||||
|
|
|
@ -47,6 +47,11 @@ public class MappedByTableGroup extends DelegatingTableGroup implements VirtualT
|
|||
return underlyingTableGroup;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TableGroup getUnderlyingTableGroup() {
|
||||
return underlyingTableGroup;
|
||||
}
|
||||
|
||||
@Override
|
||||
public NavigablePath getNavigablePath() {
|
||||
return navigablePath;
|
||||
|
|
|
@ -41,6 +41,11 @@ public class StandardVirtualTableGroup extends AbstractTableGroup implements Vir
|
|||
return getModelPart();
|
||||
}
|
||||
|
||||
@Override
|
||||
public TableGroup getUnderlyingTableGroup() {
|
||||
return underlyingTableGroup;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isFetched() {
|
||||
return fetched;
|
||||
|
|
|
@ -13,4 +13,5 @@ package org.hibernate.sql.ast.tree.from;
|
|||
* @author Steve Ebersole
|
||||
*/
|
||||
public interface VirtualTableGroup extends TableGroup {
|
||||
TableGroup getUnderlyingTableGroup();
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue