HHH-16414 Improve TableGroup resolution for get or create

This commit is contained in:
Marco Belladelli 2023-03-31 20:29:02 +02:00
parent 5cf3e9b4bf
commit f9dd723e2b
1 changed files with 30 additions and 30 deletions

View File

@ -9,14 +9,11 @@ package org.hibernate.sql.ast.spi;
import java.util.HashMap;
import java.util.Map;
import org.hibernate.metamodel.mapping.ModelPartContainer;
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.CorrelatedTableGroup;
import org.hibernate.sql.ast.tree.from.PluralTableGroup;
import org.hibernate.sql.ast.tree.from.TableGroup;
import org.hibernate.sql.ast.tree.from.VirtualTableGroup;
import org.jboss.logging.Logger;
@ -54,38 +51,41 @@ public class SimpleFromClauseAccessImpl implements FromClauseAccess {
@Override
public TableGroup findTableGroupForGetOrCreate(NavigablePath navigablePath) {
final TableGroup tableGroup = findTableGroup( navigablePath );
if ( parent != null && tableGroup != null && navigablePath.getParent() != null ) {
final NavigableRole navigableRole = tableGroup.getModelPart().getNavigableRole();
if ( navigableRole != null && navigableRole.getParent() != 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 ( getUnderlyingTableGroup( findTableGroup( parentPath ) ) == getUnderlyingTableGroup( tableGroup ) ) {
return tableGroup;
}
else {
return null;
final TableGroup localTableGroup = tableGroupMap.get( navigablePath );
if ( localTableGroup != null || parent == null ) {
return localTableGroup;
}
else {
final TableGroup tableGroup = parent.findTableGroup( navigablePath );
if ( tableGroup != null && navigablePath.getParent() != null ) {
final NavigableRole navigableRole = tableGroup.getModelPart().getNavigableRole();
if ( navigableRole.getParent() != null ) {
// Traverse up the navigable path to the point where resolving the path leads us to the parent TableGroup
NavigableRole parentRole = navigableRole.getParent();
NavigablePath parentPath = navigablePath.getParent();
while ( parentRole.getParent() != null ) {
parentRole = parentRole.getParent();
parentPath = parentPath.getParent();
}
final TableGroup parentFound = parent.findTableGroup( parentPath );
// Only return the TableGroup if there's no corresponding group in the parent FromClauseAccess
// or if there is one, but it's the same or correlated to the locally found one.
if ( parentFound == null || getCorrelatedTableGroup( parentFound ) == getCorrelatedTableGroup(
tableGroupMap.get( parentPath ) ) ) {
return tableGroup;
}
else {
return null;
}
}
}
return tableGroup;
}
return tableGroup;
}
private TableGroup getUnderlyingTableGroup(TableGroup tableGroup) {
if ( tableGroup instanceof VirtualTableGroup ) {
return getUnderlyingTableGroup( ( (VirtualTableGroup) tableGroup ).getUnderlyingTableGroup() );
}
else if ( tableGroup instanceof CorrelatedTableGroup ) {
return getUnderlyingTableGroup( ( (CorrelatedTableGroup) tableGroup ).getCorrelatedTableGroup() );
}
else if ( tableGroup instanceof PluralTableGroup ) {
return ( (PluralTableGroup) tableGroup ).getElementTableGroup();
private TableGroup getCorrelatedTableGroup(TableGroup tableGroup) {
if ( tableGroup instanceof CorrelatedTableGroup ) {
return getCorrelatedTableGroup( ( (CorrelatedTableGroup) tableGroup ).getCorrelatedTableGroup() );
}
return tableGroup;
}