Skip to content

Commit 49886d1

Browse files
committed
HHH-18610 SQLGrammarException: Unable to find column position by name: TYPE when using Single Table Inheritance with a strict JDBC driver such as PostgreSQL
1 parent cd47e91 commit 49886d1

25 files changed

+549
-417
lines changed

hibernate-core/src/main/java/org/hibernate/metamodel/mapping/EntityIdentifierMapping.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
import jakarta.persistence.EmbeddedId;
1414
import jakarta.persistence.Id;
1515
import jakarta.persistence.IdClass;
16+
import org.hibernate.sql.results.graph.Fetchable;
1617

1718

1819
/**
@@ -22,7 +23,7 @@
2223
* @see EmbeddedId
2324
* @see Nature
2425
*/
25-
public interface EntityIdentifierMapping extends ValuedModelPart {
26+
public interface EntityIdentifierMapping extends ValuedModelPart, Fetchable {
2627

2728
String ID_ROLE_NAME = "{id}";
2829
String LEGACY_ID_NAME = "id";

hibernate-core/src/main/java/org/hibernate/query/NativeQuery.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
import org.hibernate.metamodel.mapping.PluralAttributeMapping;
2222
import org.hibernate.metamodel.model.domain.BasicDomainType;
2323
import org.hibernate.spi.NavigablePath;
24+
import org.hibernate.sql.results.graph.Fetchable;
2425
import org.hibernate.transform.ResultTransformer;
2526
import org.hibernate.type.BasicTypeReference;
2627

@@ -504,6 +505,8 @@ interface FetchReturn extends ResultNode {
504505

505506
String getOwnerAlias();
506507

508+
Fetchable getFetchable();
509+
507510
String getFetchableName();
508511

509512
/**

hibernate-core/src/main/java/org/hibernate/query/internal/FetchMementoHbmStandard.java

Lines changed: 99 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
public class FetchMementoHbmStandard implements FetchMemento, FetchMemento.Parent {
3131

3232
private static final String ELEMENT_PREFIX = "element.";
33+
private static final int ELEMENT_PREFIX_LENGTH = 8;
3334

3435
public interface FetchParentMemento {
3536
NavigablePath getNavigablePath();
@@ -74,55 +75,110 @@ public FetchBuilder resolve(
7475
Parent parent,
7576
Consumer<String> querySpaceConsumer,
7677
ResultSetMappingResolutionContext context) {
77-
final Map<String, FetchBuilder> fetchBuilderMap = new HashMap<>();
78-
fetchMementoMap.forEach(
79-
(attrName, fetchMemento) -> fetchBuilderMap.put(
80-
attrName,
81-
fetchMemento.resolve(this, querySpaceConsumer, context )
82-
)
83-
);
84-
final DynamicResultBuilderEntityStandard resultBuilder;
85-
if ( fetchable instanceof PluralAttributeMapping ) {
86-
resultBuilder = new DynamicResultBuilderEntityStandard(
87-
(EntityMappingType) ( (PluralAttributeMapping) fetchable ).getElementDescriptor().getPartMappingType(),
88-
tableAlias,
89-
navigablePath
90-
);
91-
FetchBuilder element = fetchBuilderMap.get( "element" );
92-
if ( element != null ) {
93-
if ( element instanceof DynamicFetchBuilder ) {
94-
resultBuilder.addIdColumnAliases(
95-
( (DynamicFetchBuilder) element ).getColumnAliases().toArray( new String[0] )
96-
);
97-
}
98-
else {
99-
resultBuilder.addIdColumnAliases(
100-
( (CompleteFetchBuilderEntityValuedModelPart) element ).getColumnAliases().toArray( new String[0] )
101-
);
102-
}
103-
}
104-
FetchBuilder index = fetchBuilderMap.get( "index" );
105-
if ( index != null ) {
106-
resultBuilder.addFetchBuilder( CollectionPart.Nature.INDEX.getName(), index );
107-
}
108-
for ( Map.Entry<String, FetchBuilder> entry : fetchBuilderMap.entrySet() ) {
109-
if ( entry.getKey().startsWith( ELEMENT_PREFIX ) ) {
110-
resultBuilder.addFetchBuilder( entry.getKey().substring( ELEMENT_PREFIX.length() ), entry.getValue() );
111-
}
112-
}
78+
if ( fetchable instanceof PluralAttributeMapping pluralAttributeMapping ) {
79+
return resolve( pluralAttributeMapping, querySpaceConsumer, context );
11380
}
11481
else {
115-
resultBuilder = new DynamicResultBuilderEntityStandard(
116-
( (ToOneAttributeMapping) fetchable ).getEntityMappingType(),
117-
tableAlias,
118-
navigablePath
119-
);
120-
fetchBuilderMap.forEach( resultBuilder::addFetchBuilder );
82+
return resolve( (ToOneAttributeMapping) fetchable, querySpaceConsumer, context );
12183
}
84+
}
85+
86+
private FetchBuilder resolve(
87+
PluralAttributeMapping pluralAttributeMapping,
88+
Consumer<String> querySpaceConsumer,
89+
ResultSetMappingResolutionContext context) {
90+
final DynamicResultBuilderEntityStandard resultBuilder;
91+
EntityMappingType partMappingType = (EntityMappingType) pluralAttributeMapping.getElementDescriptor()
92+
.getPartMappingType();
93+
resultBuilder = new DynamicResultBuilderEntityStandard(
94+
partMappingType,
95+
tableAlias,
96+
navigablePath
97+
);
98+
final Map<Fetchable, FetchBuilder> fetchBuilderMap = new HashMap<>();
99+
fetchMementoMap.forEach(
100+
(attrName, fetchMemento) -> {
101+
final FetchBuilder fetchBuilder = fetchMemento.resolve( this, querySpaceConsumer, context );
102+
103+
if ( attrName.equals( "element" ) ) {
104+
if ( fetchBuilder instanceof DynamicFetchBuilder dynamicFetchBuilder ) {
105+
resultBuilder.addIdColumnAliases(
106+
dynamicFetchBuilder.getColumnAliases().toArray( new String[0] )
107+
);
108+
}
109+
else {
110+
resultBuilder.addIdColumnAliases(
111+
((CompleteFetchBuilderEntityValuedModelPart) fetchBuilder).getColumnAliases()
112+
.toArray( new String[0] )
113+
);
114+
}
115+
fetchBuilderMap.put(
116+
pluralAttributeMapping.getElementDescriptor(),
117+
fetchBuilder
118+
);
119+
}
120+
else if ( attrName.equals( "index" ) ) {
121+
final CollectionPart indexDescriptor = pluralAttributeMapping.getIndexDescriptor();
122+
resultBuilder.addFetchBuilder( indexDescriptor, fetchBuilder );
123+
fetchBuilderMap.put(
124+
indexDescriptor,
125+
fetchBuilder
126+
);
127+
}
128+
else if ( attrName.startsWith( ELEMENT_PREFIX ) ) {
129+
final Fetchable attributeMapping = (Fetchable) partMappingType.findByPath(
130+
attrName.substring( ELEMENT_PREFIX_LENGTH ) );
131+
resultBuilder.addFetchBuilder( attributeMapping, fetchBuilder );
132+
fetchBuilderMap.put(
133+
attributeMapping,
134+
fetchBuilder
135+
);
136+
}
137+
else {
138+
final Fetchable attributeMapping = (Fetchable) partMappingType.findByPath( attrName );
139+
resultBuilder.addFetchBuilder( attributeMapping, fetchBuilder );
140+
fetchBuilderMap.put(
141+
attributeMapping,
142+
fetchBuilder
143+
);
144+
}
145+
}
146+
);
147+
return new DynamicFetchBuilderLegacy(
148+
tableAlias,
149+
ownerTableAlias,
150+
fetchable,
151+
keyColumnNames,
152+
fetchBuilderMap,
153+
resultBuilder
154+
);
155+
}
156+
157+
private FetchBuilder resolve(
158+
ToOneAttributeMapping toOneAttributeMapping,
159+
Consumer<String> querySpaceConsumer,
160+
ResultSetMappingResolutionContext context) {
161+
final Map<Fetchable, FetchBuilder> fetchBuilderMap = new HashMap<>();
162+
fetchMementoMap.forEach(
163+
(attrName, fetchMemento) ->
164+
fetchBuilderMap.put(
165+
(Fetchable) toOneAttributeMapping.findSubPart( attrName ),
166+
fetchMemento.resolve( this, querySpaceConsumer, context )
167+
)
168+
);
169+
final DynamicResultBuilderEntityStandard resultBuilder;
170+
resultBuilder = new DynamicResultBuilderEntityStandard(
171+
toOneAttributeMapping.getEntityMappingType(),
172+
tableAlias,
173+
navigablePath
174+
);
175+
fetchBuilderMap.forEach( (fetchable, fetchBuilder) ->
176+
resultBuilder.addFetchBuilder( fetchable, fetchBuilder )
177+
);
122178
return new DynamicFetchBuilderLegacy(
123179
tableAlias,
124180
ownerTableAlias,
125-
fetchable.getFetchableName(),
181+
fetchable,
126182
keyColumnNames,
127183
fetchBuilderMap,
128184
resultBuilder

hibernate-core/src/main/java/org/hibernate/query/internal/ResultMementoEntityJpa.java

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
import org.hibernate.query.results.internal.complete.DelayedFetchBuilderBasicPart;
2424
import org.hibernate.query.results.internal.implicit.ImplicitFetchBuilderBasic;
2525
import org.hibernate.spi.NavigablePath;
26+
import org.hibernate.sql.results.graph.Fetchable;
2627

2728
/**
2829
* @author Steve Ebersole
@@ -70,13 +71,13 @@ public ResultBuilderEntityValued resolve(
7071
}
7172
}
7273

73-
final HashMap<String, FetchBuilder> explicitFetchBuilderMap = new HashMap<>();
74+
final HashMap<Fetchable, FetchBuilder> explicitFetchBuilderMap = new HashMap<>();
7475

7576
// If there are no explicit fetches, we don't register DELAYED builders to get implicit fetching of all basic fetchables
7677
if ( !explicitFetchMementoMap.isEmpty() ) {
7778
explicitFetchMementoMap.forEach(
7879
(relativePath, fetchMemento) -> explicitFetchBuilderMap.put(
79-
relativePath,
80+
(Fetchable) entityDescriptor.findByPath( relativePath ),
8081
fetchMemento.resolve( this, querySpaceConsumer, context )
8182
)
8283
);
@@ -87,13 +88,13 @@ public ResultBuilderEntityValued resolve(
8788
attributeMapping -> {
8889
final BasicValuedModelPart basicPart = attributeMapping.asBasicValuedModelPart();
8990
if ( basicPart != null ) {
90-
final Function<String, FetchBuilder> fetchBuilderCreator = k -> new DelayedFetchBuilderBasicPart(
91-
navigablePath.append( k ),
91+
final Function<Fetchable, FetchBuilder> fetchBuilderCreator = k -> new DelayedFetchBuilderBasicPart(
92+
navigablePath.append( k.getFetchableName() ),
9293
basicPart,
9394
isEnhancedForLazyLoading
9495
);
9596
explicitFetchBuilderMap.computeIfAbsent(
96-
attributeMapping.getFetchableName(),
97+
attributeMapping,
9798
fetchBuilderCreator
9899
);
99100
}

hibernate-core/src/main/java/org/hibernate/query/internal/ResultMementoEntityStandard.java

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,15 +10,16 @@
1010

1111
import org.hibernate.LockMode;
1212
import org.hibernate.metamodel.mapping.EntityMappingType;
13+
import org.hibernate.query.results.FetchBuilderBasicValued;
1314
import org.hibernate.spi.NavigablePath;
1415
import org.hibernate.query.QueryLogging;
1516
import org.hibernate.query.named.FetchMemento;
1617
import org.hibernate.query.named.FetchMementoBasic;
1718
import org.hibernate.query.named.ResultMementoEntity;
18-
import org.hibernate.query.results.FetchBuilderBasicValued;
1919
import org.hibernate.query.results.FetchBuilder;
2020
import org.hibernate.query.results.ResultBuilderEntityValued;
2121
import org.hibernate.query.results.internal.complete.CompleteResultBuilderEntityStandard;
22+
import org.hibernate.sql.results.graph.Fetchable;
2223

2324
/**
2425
* @author Steve Ebersole
@@ -64,11 +65,11 @@ public ResultBuilderEntityValued resolve(
6465
? (FetchBuilderBasicValued) discriminatorMemento.resolve( this, querySpaceConsumer, context )
6566
: null;
6667

67-
final HashMap<String, FetchBuilder> fetchBuilderMap = new HashMap<>();
68+
final HashMap<Fetchable, FetchBuilder> fetchBuilderMap = new HashMap<>();
6869

6970
fetchMementoMap.forEach(
7071
(attrName, fetchMemento) -> fetchBuilderMap.put(
71-
attrName,
72+
(Fetchable) entityDescriptor.findByPath( attrName ),
7273
fetchMemento.resolve(this, querySpaceConsumer, context )
7374
)
7475
);

hibernate-core/src/main/java/org/hibernate/query/results/FetchBuilder.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
import org.hibernate.sql.results.graph.DomainResultCreationState;
1010
import org.hibernate.sql.results.graph.Fetch;
1111
import org.hibernate.sql.results.graph.FetchParent;
12+
import org.hibernate.sql.results.graph.Fetchable;
1213
import org.hibernate.sql.results.jdbc.spi.JdbcValuesMetadata;
1314

1415
import java.util.function.BiConsumer;
@@ -33,7 +34,7 @@ Fetch buildFetch(
3334
JdbcValuesMetadata jdbcResultsMetadata,
3435
DomainResultCreationState domainResultCreationState);
3536

36-
default void visitFetchBuilders(BiConsumer<String, FetchBuilder> consumer) {
37+
default void visitFetchBuilders(BiConsumer<Fetchable, FetchBuilder> consumer) {
3738
}
3839

3940
FetchBuilder cacheKeyInstance();

hibernate-core/src/main/java/org/hibernate/query/results/LegacyFetchBuilder.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44
*/
55
package org.hibernate.query.results;
66

7+
import org.hibernate.sql.results.graph.Fetchable;
8+
79
/**
810
* Specialized FetchBuilder implementations which handle building fetches defined via:<ul>
911
* <li>{@code hbm.xml} definitions</li>
@@ -30,4 +32,6 @@ public interface LegacyFetchBuilder extends FetchBuilder {
3032

3133
@Override
3234
LegacyFetchBuilder cacheKeyInstance();
35+
36+
Fetchable getFetchable();
3337
}

hibernate-core/src/main/java/org/hibernate/query/results/ResultBuilder.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
import org.hibernate.Incubating;
88
import org.hibernate.sql.results.graph.DomainResult;
99
import org.hibernate.sql.results.graph.DomainResultCreationState;
10+
import org.hibernate.sql.results.graph.Fetchable;
1011
import org.hibernate.sql.results.jdbc.spi.JdbcValuesMetadata;
1112

1213
import java.util.function.BiConsumer;
@@ -46,6 +47,6 @@ DomainResult<?> buildResult(
4647

4748
ResultBuilder cacheKeyInstance();
4849

49-
default void visitFetchBuilders(BiConsumer<String, FetchBuilder> consumer) {
50+
default void visitFetchBuilders(BiConsumer<Fetchable, FetchBuilder> consumer) {
5051
}
5152
}

hibernate-core/src/main/java/org/hibernate/query/results/internal/Builders.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -240,8 +240,8 @@ public static DynamicResultBuilderEntityCalculated entityCalculated(
240240
return new DynamicResultBuilderEntityCalculated( entityMapping, tableAlias, explicitLockMode );
241241
}
242242

243-
public static DynamicFetchBuilderLegacy fetch(String tableAlias, String ownerTableAlias, String joinPropertyName) {
244-
return new DynamicFetchBuilderLegacy( tableAlias, ownerTableAlias, joinPropertyName, new ArrayList<>(), new HashMap<>() );
243+
public static DynamicFetchBuilderLegacy fetch(String tableAlias, String ownerTableAlias, Fetchable fetchable) {
244+
return new DynamicFetchBuilderLegacy( tableAlias, ownerTableAlias, fetchable, new ArrayList<>(), new HashMap<>() );
245245
}
246246

247247
public static ResultBuilder resultClassBuilder(

0 commit comments

Comments
 (0)