Skip to content

Commit 2cb1134

Browse files
HHH-15070 - fix NPE for NamedNativeQuery + SqlResultSetMapping (columns)
1 parent 3630fba commit 2cb1134

File tree

3 files changed

+65
-3
lines changed

3 files changed

+65
-3
lines changed

Diff for: hibernate-core/src/main/java/org/hibernate/query/results/complete/CompleteResultBuilderBasicValuedStandard.java

+2-2
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@
2727
/**
2828
* ResultBuilder for scalar results defined via:<ul>
2929
* <li>JPA {@link jakarta.persistence.ColumnResult}</li>
30-
* <li>`<return-scalar/>` as part of a `<resultset/>` stanza in `hbm.xml`</li>
30+
* <li>`&lt;return-scalar/&gt;` as part of a `&lt;resultset/&gt;` stanza in `hbm.xml`</li>
3131
* </ul>
3232
*
3333
* @author Steve Ebersole
@@ -60,7 +60,7 @@ public ResultBuilder cacheKeyInstance() {
6060

6161
@Override
6262
public Class<?> getJavaType() {
63-
return explicitJavaType.getJavaTypeClass();
63+
return explicitJavaType == null ? null : explicitJavaType.getJavaTypeClass();
6464
}
6565

6666
@Override

Diff for: hibernate-core/src/main/java/org/hibernate/query/sql/internal/NativeQueryImpl.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -278,7 +278,7 @@ else if ( resultJavaType != null && resultJavaType != Object[].class ) {
278278
throw new IllegalArgumentException( "Named query exists but its result type is not compatible" );
279279
case 1:
280280
final Class<?> actualResultJavaType = resultSetMapping.getResultBuilders().get( 0 ).getJavaType();
281-
if ( !resultJavaType.isAssignableFrom( actualResultJavaType ) ) {
281+
if ( actualResultJavaType != null && !resultJavaType.isAssignableFrom( actualResultJavaType ) ) {
282282
throw buildIncompatibleException( resultJavaType, actualResultJavaType );
283283
}
284284
break;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
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.orm.test.query.resultmapping;
8+
9+
import org.hibernate.cfg.AvailableSettings;
10+
11+
import org.hibernate.testing.TestForIssue;
12+
import org.hibernate.testing.orm.junit.EntityManagerFactoryScope;
13+
import org.hibernate.testing.orm.junit.Jpa;
14+
import org.hibernate.testing.orm.junit.Setting;
15+
import org.junit.jupiter.api.Assertions;
16+
import org.junit.jupiter.api.Test;
17+
18+
import jakarta.persistence.ColumnResult;
19+
import jakarta.persistence.Entity;
20+
import jakarta.persistence.GeneratedValue;
21+
import jakarta.persistence.Id;
22+
import jakarta.persistence.NamedNativeQuery;
23+
import jakarta.persistence.SqlResultSetMapping;
24+
25+
/**
26+
* @author Nathan Xu
27+
*/
28+
@Jpa(
29+
annotatedClasses = NamedNativeQueryTest.Sample.class,
30+
properties = @Setting(name = AvailableSettings.GLOBALLY_QUOTED_IDENTIFIERS, value = "true")
31+
)
32+
@TestForIssue(jiraKey = "HHH-15070")
33+
class NamedNativeQueryTest {
34+
35+
@Test
36+
void test(EntityManagerFactoryScope scope) {
37+
scope.inTransaction( em ->
38+
Assertions.assertDoesNotThrow(
39+
() -> em.createNamedQuery( "sample.count", Long.class ),
40+
"without fixing, NullPointerException would be thrown"
41+
)
42+
);
43+
}
44+
45+
@SqlResultSetMapping(
46+
name = "mapping",
47+
columns = @ColumnResult( name = "cnt" )
48+
)
49+
@NamedNativeQuery(
50+
name = "sample.count",
51+
resultSetMapping = "mapping",
52+
query = "SELECT count(*) AS cnt FROM Sample"
53+
)
54+
@Entity(name = "Sample")
55+
static class Sample {
56+
57+
@Id
58+
@GeneratedValue
59+
Long id;
60+
61+
}
62+
}

0 commit comments

Comments
 (0)