Skip to content

Commit 5a27b2a

Browse files
mbelladebeikov
authored andcommitted
HHH-17483 Fix applyDiscriminator treat for nested inheritance subtypes
Also small fix to joined-inheritance pruning.
1 parent 98ba4fc commit 5a27b2a

File tree

5 files changed

+53
-21
lines changed

5 files changed

+53
-21
lines changed

hibernate-core/src/main/java/org/hibernate/persister/entity/AbstractEntityPersister.java

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3037,7 +3037,7 @@ protected void logStaticSQL() {
30373037

30383038
public abstract Map<Object, String> getSubclassByDiscriminatorValue();
30393039

3040-
protected abstract boolean needsDiscriminator();
3040+
public abstract boolean needsDiscriminator();
30413041

30423042
protected boolean isDiscriminatorFormula() {
30433043
return false;
@@ -3130,7 +3130,25 @@ public void applyDiscriminator(
31303130
TableGroup tableGroup,
31313131
SqlAstCreationState creationState) {
31323132
if ( needsDiscriminator() ) {
3133-
pruneForSubclasses( tableGroup, Collections.singletonMap( getEntityName(), EntityNameUse.TREAT ) );
3133+
assert !creationState.supportsEntityNameUsage() : "Entity name usage should have been used instead";
3134+
final Map<String, EntityNameUse> entityNameUseMap;
3135+
final Collection<EntityMappingType> subMappingTypes = getSubMappingTypes();
3136+
if ( subMappingTypes.isEmpty() ) {
3137+
entityNameUseMap = Collections.singletonMap( getEntityName(), EntityNameUse.TREAT );
3138+
}
3139+
else {
3140+
entityNameUseMap = new HashMap<>( 1 + subMappingTypes.size() );
3141+
entityNameUseMap.put( getEntityName(), EntityNameUse.TREAT );
3142+
// We need to register TREAT uses for all subtypes when pruning
3143+
for ( EntityMappingType subMappingType : subMappingTypes ) {
3144+
entityNameUseMap.put( subMappingType.getEntityName(), EntityNameUse.TREAT );
3145+
}
3146+
if ( isInherited() ) {
3147+
// Make sure the table group includes the root table when needed for TREAT
3148+
tableGroup.resolveTableReference( getRootTableName() );
3149+
}
3150+
}
3151+
pruneForSubclasses( tableGroup, entityNameUseMap );
31343152
}
31353153
}
31363154

hibernate-core/src/main/java/org/hibernate/persister/entity/JoinedSubclassEntityPersister.java

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -744,7 +744,7 @@ private void associateSubclassNamesToSubclassTableIndex(
744744
}
745745

746746
@Override
747-
protected boolean needsDiscriminator() {
747+
public boolean needsDiscriminator() {
748748
return forceDiscriminator;
749749
}
750750

@@ -1325,15 +1325,17 @@ public void pruneForSubclasses(TableGroup tableGroup, Map<String, EntityNameUse>
13251325
final String[] subclassTableNames = persister.getSubclassTableNames();
13261326
// Build the intersection of all tables names that are of the class or super class
13271327
// These are the tables that can be safely inner joined
1328-
if ( tablesToInnerJoin.isEmpty() ) {
1329-
for ( int i = 0; i < subclassTableNames.length; i++ ) {
1330-
if ( persister.isClassOrSuperclassTable[i] ) {
1331-
tablesToInnerJoin.add( subclassTableNames[i] );
1332-
}
1328+
final Set<String> classOrSuperclassTables = new HashSet<>( subclassTableNames.length );
1329+
for ( int i = 0; i < subclassTableNames.length; i++ ) {
1330+
if ( persister.isClassOrSuperclassTable[i] ) {
1331+
classOrSuperclassTables.add( subclassTableNames[i] );
13331332
}
13341333
}
1334+
if ( tablesToInnerJoin.isEmpty() ) {
1335+
tablesToInnerJoin.addAll( classOrSuperclassTables );
1336+
}
13351337
else {
1336-
tablesToInnerJoin.retainAll( Arrays.asList( subclassTableNames ) );
1338+
tablesToInnerJoin.retainAll( classOrSuperclassTables );
13371339
}
13381340
if ( useKind == EntityNameUse.UseKind.FILTER && explicitDiscriminatorColumnName == null ) {
13391341
// If there is no discriminator column,

hibernate-core/src/main/java/org/hibernate/persister/entity/SingleTableEntityPersister.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -548,7 +548,7 @@ public String fromTableFragment(String name) {
548548
}
549549

550550
@Override
551-
protected boolean needsDiscriminator() {
551+
public boolean needsDiscriminator() {
552552
return forceDiscriminator || isInherited();
553553
}
554554

hibernate-core/src/main/java/org/hibernate/persister/entity/UnionSubclassEntityPersister.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -286,7 +286,7 @@ public TableGroup createRootTableGroup(
286286
}
287287

288288
@Override
289-
protected boolean needsDiscriminator() {
289+
public boolean needsDiscriminator() {
290290
return false;
291291
}
292292

hibernate-core/src/main/java/org/hibernate/query/sqm/sql/BaseSqmToSqlAstConverter.java

Lines changed: 22 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3102,20 +3102,30 @@ private void registerEntityNameUsage(
31023102
);
31033103
}
31043104
}
3105-
if ( useKind == EntityNameUse.UseKind.TREAT || useKind == EntityNameUse.UseKind.PROJECTION ) {
3106-
// If we encounter a treat use, we also want register the use for all subtypes.
3107-
// We do this here to not have to expand entity name uses during pruning later on
3105+
// If we encounter a treat or projection use, we also want register the use for all subtypes.
3106+
// We do this here to not have to expand entity name uses during pruning later on
3107+
if ( useKind == EntityNameUse.UseKind.TREAT ) {
31083108
for ( EntityMappingType subType : persister.getSubMappingTypes() ) {
31093109
entityNameUses.compute(
31103110
subType.getEntityName(),
31113111
(s, existingUse) -> finalEntityNameUse.stronger( existingUse )
31123112
);
3113-
if ( useKind == EntityNameUse.UseKind.PROJECTION ) {
3114-
actualTableGroup.resolveTableReference(
3115-
null,
3116-
subType.getEntityPersister().getMappedTableDetails().getTableName()
3117-
);
3118-
}
3113+
}
3114+
if ( persister.isInherited() && persister.needsDiscriminator() ) {
3115+
// Make sure the table group includes the root table when needed for TREAT
3116+
actualTableGroup.resolveTableReference( persister.getRootTableName() );
3117+
}
3118+
}
3119+
else if ( useKind == EntityNameUse.UseKind.PROJECTION ) {
3120+
for ( EntityMappingType subType : persister.getSubMappingTypes() ) {
3121+
entityNameUses.compute(
3122+
subType.getEntityName(),
3123+
(s, existingUse) -> finalEntityNameUse.stronger( existingUse )
3124+
);
3125+
actualTableGroup.resolveTableReference(
3126+
null,
3127+
subType.getEntityPersister().getMappedTableDetails().getTableName()
3128+
);
31193129
}
31203130
}
31213131
}
@@ -8217,7 +8227,9 @@ else if ( getLoadQueryInfluencers().hasEnabledFetchProfiles() ) {
82178227
if ( entityMappingType.getSuperMappingType() != null ) {
82188228
// A joined table group was created by an enabled entity graph or fetch profile,
82198229
// and it's of an inheritance subtype, so we should apply the discriminator
8220-
entityMappingType.applyDiscriminator( null, null, actualTableGroup, this );
8230+
getCurrentClauseStack().push( Clause.FROM );
8231+
registerEntityNameUsage( actualTableGroup, EntityNameUse.TREAT, entityMappingType.getEntityName() );
8232+
getCurrentClauseStack().pop();
82218233
}
82228234
}
82238235
}

0 commit comments

Comments
 (0)