Skip to content

Commit c35408c

Browse files
committed
HHH-18851 Fix parameter type inference issue when IN predicate is uses array_contains()
1 parent 7cdab31 commit c35408c

File tree

4 files changed

+50
-25
lines changed

4 files changed

+50
-25
lines changed

hibernate-core/src/main/java/org/hibernate/dialect/function/array/ArrayContainsArgumentTypeResolver.java

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,10 +43,15 @@ public class ArrayContainsArgumentTypeResolver extends AbstractFunctionArgumentT
4343
}
4444
}
4545
else if ( argumentIndex == 1 ) {
46+
final SqmTypedNode<?> nodeToResolve = arguments.get( 1 );
47+
if ( nodeToResolve.getExpressible() instanceof MappingModelExpressible<?> ) {
48+
// If the node already has suitable type, don't infer it to be treated as an array
49+
return null;
50+
}
4651
final SqmTypedNode<?> node = arguments.get( 0 );
4752
if ( node instanceof SqmExpression<?> ) {
4853
final MappingModelExpressible<?> expressible = converter.determineValueMapping( (SqmExpression<?>) node );
49-
if ( expressible != null ) {
54+
if ( expressible instanceof BasicPluralType<?, ?> ) {
5055
return expressible;
5156
}
5257
}

hibernate-core/src/main/java/org/hibernate/query/hql/internal/SemanticQueryBuilder.java

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3494,11 +3494,14 @@ else if ( inListContext instanceof HqlParser.ArrayInListContext ) {
34943494

34953495
final SqmExpression<?> arrayExpr = (SqmExpression<?>) arrayInListContext.expression().accept( this );
34963496
final SqmExpressible<?> arrayExpressible = arrayExpr.getExpressible();
3497-
if ( arrayExpressible != null && !( arrayExpressible.getSqmType() instanceof BasicPluralType<?, ?>) ) {
3498-
throw new SemanticException(
3499-
"Right operand for in-array predicate must be a basic plural type expression, but found: " + arrayExpressible.getSqmType(),
3500-
query
3501-
);
3497+
if ( arrayExpressible != null ) {
3498+
if ( !(arrayExpressible.getSqmType() instanceof BasicPluralType<?, ?> pluralType) ) {
3499+
throw new SemanticException(
3500+
"Right operand for in-array predicate must be a basic plural type expression, but found: " + arrayExpressible.getSqmType(),
3501+
query
3502+
);
3503+
}
3504+
testExpression.applyInferableType( pluralType.getElementType() );
35023505
}
35033506
final SelfRenderingSqmFunction<Boolean> contains = getFunctionDescriptor( "array_contains" ).generateSqmExpression(
35043507
asList( arrayExpr, testExpression ),

hibernate-core/src/test/java/org/hibernate/orm/test/function/array/ArrayContainsTest.java

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
import org.hibernate.testing.orm.junit.BootstrapServiceRegistry;
1616
import org.hibernate.testing.orm.junit.DialectFeatureChecks;
1717
import org.hibernate.testing.orm.junit.DomainModel;
18+
import org.hibernate.testing.orm.junit.JiraKey;
1819
import org.hibernate.testing.orm.junit.RequiresDialectFeature;
1920
import org.hibernate.testing.orm.junit.SessionFactory;
2021
import org.hibernate.testing.orm.junit.SessionFactoryScope;
@@ -156,4 +157,22 @@ public void testInSyntax(SessionFactoryScope scope) {
156157
} );
157158
}
158159

160+
@Test
161+
@JiraKey( "HHH-18851" )
162+
public void testInArray(SessionFactoryScope scope) {
163+
scope.inSession( em -> {
164+
List<Tuple> results = em.createQuery(
165+
"select e.id " +
166+
"from EntityWithArrays e " +
167+
"where :p in e.theArray",
168+
Tuple.class
169+
)
170+
.setParameter( "p", "abc" )
171+
.getResultList();
172+
173+
assertEquals( 1, results.size() );
174+
assertEquals( 2L, results.get( 0 ).get( 0 ) );
175+
} );
176+
}
177+
159178
}
Lines changed: 17 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
/*
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>.
2+
* SPDX-License-Identifier: LGPL-2.1-or-later
3+
* Copyright Red Hat Inc. and Hibernate Authors
64
*/
75
package org.hibernate.orm.test.id.idClass;
86

@@ -16,23 +14,23 @@
1614
import static org.assertj.core.api.Assertions.assertThat;
1715

1816
@DomainModel(
19-
annotatedClasses = MyEntity.class
17+
annotatedClasses = MyEntity.class
2018
)
2119
@SessionFactory
2220
public class IdClassSyntheticAttributesTest {
2321

24-
@Jira("https://hibernate.atlassian.net/browse/HHH-18841")
25-
@Test
26-
public void test(DomainModelScope scope) {
27-
final PersistentClass entityBinding = scope.getDomainModel().getEntityBinding(MyEntity.class.getName());
28-
assertThat(entityBinding.getProperties()).hasSize(2)
29-
.anySatisfy(p -> {
30-
assertThat(p.isSynthetic()).isTrue();
31-
assertThat(p.getName()).isEqualTo("_identifierMapper");
32-
})
33-
.anySatisfy(p -> {
34-
assertThat(p.isSynthetic()).isFalse();
35-
assertThat(p.getName()).isEqualTo("notes");
36-
});
37-
}
22+
@Jira("https://hibernate.atlassian.net/browse/HHH-18841")
23+
@Test
24+
public void test(DomainModelScope scope) {
25+
final PersistentClass entityBinding = scope.getDomainModel().getEntityBinding(MyEntity.class.getName());
26+
assertThat(entityBinding.getProperties()).hasSize(2)
27+
.anySatisfy(p -> {
28+
assertThat(p.isSynthetic()).isTrue();
29+
assertThat(p.getName()).isEqualTo("_identifierMapper");
30+
})
31+
.anySatisfy(p -> {
32+
assertThat(p.isSynthetic()).isFalse();
33+
assertThat(p.getName()).isEqualTo("notes");
34+
});
35+
}
3836
}

0 commit comments

Comments
 (0)