Skip to content

Commit 9c660f7

Browse files
beikovdreab8
authored andcommitted
HHH-15367 Lift embedded/id-class to-one selection limitation for from clause subqueries
1 parent 7676af4 commit 9c660f7

32 files changed

+3664
-168
lines changed

documentation/src/test/java/org/hibernate/userguide/hql/HQLTest.java

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,6 @@
3232
import org.hibernate.dialect.PostgreSQLDialect;
3333
import org.hibernate.dialect.SQLServerDialect;
3434
import org.hibernate.dialect.SybaseASEDialect;
35-
import org.hibernate.dialect.TiDBDialect;
3635
import org.hibernate.orm.test.jpa.BaseEntityManagerFunctionalTestCase;
3736
import org.hibernate.query.QueryProducer;
3837
import org.hibernate.type.StandardBasicTypes;
@@ -2037,7 +2036,7 @@ public void test_hql_collection_index_operator_example_2() {
20372036
}
20382037

20392038
@Test
2040-
@SkipForDialect(value = TiDBDialect.class, comment = "TiDB db does not support subqueries for ON condition")
2039+
@RequiresDialectFeature(DialectChecks.SupportsSubqueryInOnClause.class)
20412040
public void test_hql_collection_index_operator_example_3() {
20422041
doInJPA(this::entityManagerFactory, entityManager -> {
20432042
//tag::hql-collection-index-operator-example[]
@@ -3081,8 +3080,10 @@ public void test_hql_derived_root_example() {
30813080
}
30823081

30833082
@Test
3084-
@SkipForDialect(value = TiDBDialect.class, comment = "TiDB db does not support subqueries for ON condition")
3085-
@RequiresDialectFeature(DialectChecks.SupportsOrderByInCorrelatedSubquery.class)
3083+
@RequiresDialectFeature({
3084+
DialectChecks.SupportsSubqueryInOnClause.class,
3085+
DialectChecks.SupportsOrderByInCorrelatedSubquery.class
3086+
})
30863087
public void test_hql_derived_join_example() {
30873088

30883089
doInJPA(this::entityManagerFactory, entityManager -> {

hibernate-core/src/main/java/org/hibernate/metamodel/internal/AbstractCompositeIdentifierMapping.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -233,7 +233,7 @@ public SqlTuple toSqlExpression(
233233
final TableReference defaultTableReference = tableGroup.resolveTableReference( navigablePath, getContainingTableExpression() );
234234
getEmbeddableTypeDescriptor().forEachSelectable(
235235
(columnIndex, selection) -> {
236-
final TableReference tableReference = defaultTableReference.resolveTableReference( selection.getContainingTableExpression() ) != null
236+
final TableReference tableReference = getContainingTableExpression().equals( selection.getContainingTableExpression() )
237237
? defaultTableReference
238238
: tableGroup.resolveTableReference( navigablePath, selection.getContainingTableExpression() );
239239
final Expression columnReference = sqlAstCreationState.getSqlExpressionResolver()

hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/EmbeddedAttributeMapping.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -256,7 +256,7 @@ public SqlTuple toSqlExpression(
256256
final TableReference defaultTableReference = tableGroup.resolveTableReference( navigablePath, getContainingTableExpression() );
257257
getEmbeddableTypeDescriptor().forEachSelectable(
258258
(columnIndex, selection) -> {
259-
final TableReference tableReference = defaultTableReference.resolveTableReference( selection.getContainingTableExpression() ) != null
259+
final TableReference tableReference = getContainingTableExpression().equals( selection.getContainingTableExpression() )
260260
? defaultTableReference
261261
: tableGroup.resolveTableReference( navigablePath, selection.getContainingTableExpression() );
262262
final Expression columnReference = sqlAstCreationState.getSqlExpressionResolver().resolveSqlExpression(

hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/ToOneAttributeMapping.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -599,7 +599,7 @@ static String findMapsIdPropertyName(EntityMappingType entityMappingType, String
599599
return null;
600600
}
601601

602-
static void addPrefixedPropertyNames(
602+
public static void addPrefixedPropertyNames(
603603
Set<String> targetKeyPropertyNames,
604604
String prefix,
605605
Type type,

hibernate-core/src/main/java/org/hibernate/query/derived/AnonymousTupleBasicValuedModelPart.java

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
import org.hibernate.sql.ast.tree.expression.ColumnReference;
3030
import org.hibernate.sql.ast.tree.expression.Expression;
3131
import org.hibernate.sql.ast.tree.from.TableGroup;
32+
import org.hibernate.sql.ast.tree.from.TableReference;
3233
import org.hibernate.sql.results.graph.DomainResult;
3334
import org.hibernate.sql.results.graph.DomainResultCreationState;
3435
import org.hibernate.sql.results.graph.FetchOptions;
@@ -186,10 +187,14 @@ private SqlSelection resolveSqlSelection(
186187
FetchParent fetchParent,
187188
SqlAstCreationState creationState) {
188189
final SqlExpressionResolver expressionResolver = creationState.getSqlExpressionResolver();
190+
final TableReference tableReference = tableGroup.resolveTableReference(
191+
navigablePath,
192+
getContainingTableExpression()
193+
);
189194
final Expression expression = expressionResolver.resolveSqlExpression(
190-
createColumnReferenceKey( tableGroup.getPrimaryTableReference(), getSelectionExpression() ),
195+
createColumnReferenceKey( tableReference, getSelectionExpression() ),
191196
sqlAstProcessingState -> new ColumnReference(
192-
tableGroup.resolveTableReference( navigablePath, "" ),
197+
tableReference,
193198
this,
194199
creationState.getCreationContext().getSessionFactory()
195200
)
Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
/*
2+
* Hibernate, Relational Persistence for Idiomatic Java
3+
*
4+
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
5+
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
6+
*/
7+
package org.hibernate.query.derived;
8+
9+
import java.util.Map;
10+
11+
import org.hibernate.Incubating;
12+
import org.hibernate.engine.spi.IdentifierValue;
13+
import org.hibernate.engine.spi.SharedSessionContractImplementor;
14+
import org.hibernate.metamodel.mapping.BasicEntityIdentifierMapping;
15+
import org.hibernate.metamodel.mapping.CompositeIdentifierMapping;
16+
import org.hibernate.metamodel.mapping.EmbeddableMappingType;
17+
import org.hibernate.metamodel.mapping.EmbeddableValuedModelPart;
18+
import org.hibernate.metamodel.mapping.JdbcMapping;
19+
import org.hibernate.metamodel.mapping.MappingType;
20+
import org.hibernate.metamodel.mapping.ModelPart;
21+
import org.hibernate.metamodel.mapping.internal.SingleAttributeIdentifierMapping;
22+
import org.hibernate.metamodel.model.domain.DomainType;
23+
import org.hibernate.property.access.spi.PropertyAccess;
24+
import org.hibernate.query.sqm.SqmExpressible;
25+
26+
/**
27+
* @author Christian Beikov
28+
*/
29+
@Incubating
30+
public class AnonymousTupleEmbeddedEntityIdentifierMapping extends AnonymousTupleEmbeddableValuedModelPart
31+
implements CompositeIdentifierMapping, SingleAttributeIdentifierMapping {
32+
33+
private final CompositeIdentifierMapping delegate;
34+
35+
public AnonymousTupleEmbeddedEntityIdentifierMapping(
36+
Map<String, ModelPart> modelParts,
37+
DomainType<?> domainType,
38+
String componentName,
39+
CompositeIdentifierMapping delegate) {
40+
super(
41+
modelParts,
42+
domainType,
43+
componentName,
44+
(EmbeddableValuedModelPart) delegate
45+
);
46+
this.delegate = delegate;
47+
}
48+
49+
@Override
50+
public IdentifierValue getUnsavedStrategy() {
51+
return delegate.getUnsavedStrategy();
52+
}
53+
54+
@Override
55+
public Object getIdentifier(Object entity, SharedSessionContractImplementor session) {
56+
return delegate.getIdentifier( entity, session );
57+
}
58+
59+
@Override
60+
public Object getIdentifier(Object entity) {
61+
return delegate.getIdentifier( entity );
62+
}
63+
64+
@Override
65+
public void setIdentifier(Object entity, Object id, SharedSessionContractImplementor session) {
66+
delegate.setIdentifier( entity, id, session );
67+
}
68+
69+
@Override
70+
public Object instantiate() {
71+
return delegate.instantiate();
72+
}
73+
74+
@Override
75+
public PropertyAccess getPropertyAccess() {
76+
return ((SingleAttributeIdentifierMapping) delegate).getPropertyAccess();
77+
}
78+
79+
@Override
80+
public String getAttributeName() {
81+
return getPartName();
82+
}
83+
84+
@Override
85+
public boolean hasContainingClass() {
86+
return true;
87+
}
88+
89+
@Override
90+
public EmbeddableMappingType getMappedIdEmbeddableTypeDescriptor() {
91+
return this;
92+
}
93+
94+
@Override
95+
public MappingType getMappedType() {
96+
return this;
97+
}
98+
99+
@Override
100+
public EmbeddableMappingType getPartMappingType() {
101+
return (EmbeddableMappingType) super.getPartMappingType();
102+
}
103+
}

0 commit comments

Comments
 (0)