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 bc31a9532a
commit 288242a10f
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.HashMap;
import java.util.Map; import java.util.Map;
import org.hibernate.metamodel.mapping.ModelPartContainer;
import org.hibernate.metamodel.model.domain.NavigableRole; import org.hibernate.metamodel.model.domain.NavigableRole;
import org.hibernate.spi.NavigablePath; import org.hibernate.spi.NavigablePath;
import org.hibernate.sql.ast.SqlTreeCreationLogger; import org.hibernate.sql.ast.SqlTreeCreationLogger;
import org.hibernate.sql.ast.tree.from.CorrelatedTableGroup; 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.TableGroup;
import org.hibernate.sql.ast.tree.from.VirtualTableGroup;
import org.jboss.logging.Logger; import org.jboss.logging.Logger;
@ -54,38 +51,41 @@ public class SimpleFromClauseAccessImpl implements FromClauseAccess {
@Override @Override
public TableGroup findTableGroupForGetOrCreate(NavigablePath navigablePath) { public TableGroup findTableGroupForGetOrCreate(NavigablePath navigablePath) {
final TableGroup tableGroup = findTableGroup( navigablePath ); final TableGroup localTableGroup = tableGroupMap.get( navigablePath );
if ( parent != null && tableGroup != null && navigablePath.getParent() != null ) { if ( localTableGroup != null || parent == null ) {
final NavigableRole navigableRole = tableGroup.getModelPart().getNavigableRole(); return localTableGroup;
if ( navigableRole != null && navigableRole.getParent() != null ) { }
// Traverse up the navigable path to the point where resolving the path leads us to a regular TableGroup else {
NavigableRole parentRole = navigableRole.getParent(); final TableGroup tableGroup = parent.findTableGroup( navigablePath );
NavigablePath parentPath = navigablePath.getParent(); if ( tableGroup != null && navigablePath.getParent() != null ) {
while ( parentRole.getParent() != null ) { final NavigableRole navigableRole = tableGroup.getModelPart().getNavigableRole();
parentRole = parentRole.getParent(); if ( navigableRole.getParent() != null ) {
parentPath = parentPath.getParent(); // Traverse up the navigable path to the point where resolving the path leads us to the parent TableGroup
} NavigableRole parentRole = navigableRole.getParent();
// Only return the TableGroup if its regular parent TableGroup corresponds to the underlying one NavigablePath parentPath = navigablePath.getParent();
if ( getUnderlyingTableGroup( findTableGroup( parentPath ) ) == getUnderlyingTableGroup( tableGroup ) ) { while ( parentRole.getParent() != null ) {
return tableGroup; parentRole = parentRole.getParent();
} parentPath = parentPath.getParent();
else { }
return null; 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) { private TableGroup getCorrelatedTableGroup(TableGroup tableGroup) {
if ( tableGroup instanceof VirtualTableGroup ) { if ( tableGroup instanceof CorrelatedTableGroup ) {
return getUnderlyingTableGroup( ( (VirtualTableGroup) tableGroup ).getUnderlyingTableGroup() ); return getCorrelatedTableGroup( ( (CorrelatedTableGroup) tableGroup ).getCorrelatedTableGroup() );
}
else if ( tableGroup instanceof CorrelatedTableGroup ) {
return getUnderlyingTableGroup( ( (CorrelatedTableGroup) tableGroup ).getCorrelatedTableGroup() );
}
else if ( tableGroup instanceof PluralTableGroup ) {
return ( (PluralTableGroup) tableGroup ).getElementTableGroup();
} }
return tableGroup; return tableGroup;
} }