Skip to content

Commit 2030aa7

Browse files
committed
HHH-10323 : Unit test failure on Oracle because constructor cannot be found
(cherry picked from commit c3ffe16)
1 parent 05f86e4 commit 2030aa7

File tree

2 files changed

+231
-0
lines changed

2 files changed

+231
-0
lines changed

hibernate-entitymanager/src/test/java/org/hibernate/jpa/test/query/ConstructorResultNativeQueryTest.java

+4
Original file line numberDiff line numberDiff line change
@@ -25,12 +25,16 @@
2525
import javax.persistence.Temporal;
2626
import javax.persistence.TemporalType;
2727

28+
import org.hibernate.dialect.Oracle8iDialect;
2829
import org.hibernate.jpa.test.BaseEntityManagerFunctionalTestCase;
30+
import org.hibernate.testing.SkipForDialect;
31+
2932
import org.junit.Test;
3033

3134
/**
3235
* @author Steve Ebersole
3336
*/
37+
@SkipForDialect(value = Oracle8iDialect.class, jiraKey = "HHH-10323")
3438
public class ConstructorResultNativeQueryTest extends BaseEntityManagerFunctionalTestCase {
3539
@Entity( name = "Person" )
3640
@SqlResultSetMappings(
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,227 @@
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.jpa.test.query;
8+
9+
import java.util.Date;
10+
import java.util.List;
11+
import javax.persistence.Column;
12+
import javax.persistence.ColumnResult;
13+
import javax.persistence.ConstructorResult;
14+
import javax.persistence.Entity;
15+
import javax.persistence.EntityManager;
16+
import javax.persistence.Id;
17+
import javax.persistence.NamedNativeQueries;
18+
import javax.persistence.NamedNativeQuery;
19+
import javax.persistence.SqlResultSetMapping;
20+
import javax.persistence.SqlResultSetMappings;
21+
import javax.persistence.Temporal;
22+
import javax.persistence.TemporalType;
23+
24+
import org.junit.Test;
25+
26+
import org.hibernate.dialect.Oracle8iDialect;
27+
import org.hibernate.jpa.test.BaseEntityManagerFunctionalTestCase;
28+
import org.hibernate.testing.RequiresDialect;
29+
30+
import static org.hibernate.testing.junit4.ExtraAssertions.assertTyping;
31+
import static org.junit.Assert.assertEquals;
32+
33+
/**
34+
* Oracle needs to have the column result type specified for the Integer ID because the
35+
* ID is mapped as an Oracle NUMBER(10,0) which is returned from the native query as a BigDecimal.
36+
* If the type is not specified, no appropriate constructor will be found because there is no
37+
* constructor that takes a BigDecimal id argument.
38+
*
39+
* This test can be run using all dialects. It is only run using Oracle, because only the Oracle
40+
* lacks a specific integer data type. Except for explicitly mapping the return values for ID as
41+
* an Integer, this test duplicates ConstructorResultNativeQueryTest.
42+
*
43+
* @author Steve Ebersole
44+
*/
45+
@RequiresDialect(value = Oracle8iDialect.class, jiraKey = "HHH-10323")
46+
public class OracleConstructorResultNativeQueryTest extends BaseEntityManagerFunctionalTestCase {
47+
@Entity( name = "Person" )
48+
@SqlResultSetMappings(
49+
value = {
50+
@SqlResultSetMapping(
51+
name = "person-id-and-name",
52+
classes = {
53+
@ConstructorResult(
54+
targetClass = Person.class,
55+
columns = {
56+
@ColumnResult( name = "id", type = Integer.class),
57+
@ColumnResult( name = "p_name" )
58+
}
59+
)
60+
}
61+
),
62+
@SqlResultSetMapping(
63+
name = "person-id-and-name2",
64+
classes = {
65+
@ConstructorResult(
66+
targetClass = Person.class,
67+
columns = {
68+
@ColumnResult( name = "id", type=Integer.class ),
69+
@ColumnResult( name = "p_name" )
70+
}
71+
),
72+
@ConstructorResult(
73+
targetClass = Person.class,
74+
columns = {
75+
@ColumnResult( name = "id2", type=Integer.class ),
76+
@ColumnResult( name = "p_name2" )
77+
}
78+
)
79+
}
80+
),
81+
@SqlResultSetMapping(
82+
name = "person-id-and-name-and-weight",
83+
classes = {
84+
@ConstructorResult(
85+
targetClass = Person.class,
86+
columns = {
87+
@ColumnResult( name = "id", type=Integer.class ),
88+
@ColumnResult( name = "p_name" ),
89+
@ColumnResult( name = "p_weight", type=String.class )
90+
}
91+
)
92+
}
93+
)
94+
}
95+
)
96+
@NamedNativeQueries(
97+
value = {
98+
@NamedNativeQuery(
99+
name = "person-id-and-name",
100+
query = "select p.id, p.p_name from person p order by p.p_name",
101+
resultSetMapping = "person-id-and-name"
102+
),
103+
@NamedNativeQuery(
104+
name = "person-id-and-name2",
105+
query = "select p.id, p.p_name, p.id as id2, p.p_name as p_name2 from person p order by p.p_name",
106+
resultSetMapping = "person-id-and-name2"
107+
),
108+
@NamedNativeQuery(
109+
name = "person-id-and-name-and-weight",
110+
query = "select p.id, p.p_name, p.p_weight from person p order by p.p_name",
111+
resultSetMapping = "person-id-and-name-and-weight"
112+
)
113+
}
114+
)
115+
public static class Person {
116+
@Id
117+
private Integer id;
118+
@Column( name = "p_name" )
119+
private String name;
120+
@Temporal( TemporalType.TIMESTAMP )
121+
private Date birthDate;
122+
@Column( name = "p_weight" )
123+
private int weight;
124+
125+
public Person() {
126+
}
127+
128+
public Person(Integer id, String name, Date birthDate) {
129+
this.id = id;
130+
this.name = name;
131+
this.birthDate = birthDate;
132+
}
133+
134+
public Person(Integer id, String name) {
135+
this.id = id;
136+
this.name = name;
137+
}
138+
139+
public Person(Integer id, String name, String weight) {
140+
this.id = id;
141+
this.name = name;
142+
this.weight = Integer.valueOf(weight);
143+
}
144+
}
145+
146+
@Override
147+
protected Class<?>[] getAnnotatedClasses() {
148+
return new Class[] { Person.class };
149+
}
150+
151+
152+
@Test
153+
public void testConstructorResultNativeQuery() {
154+
EntityManager em = getOrCreateEntityManager();
155+
em.getTransaction().begin();
156+
em.persist( new Person( 1, "John", new Date() ) );
157+
em.getTransaction().commit();
158+
em.close();
159+
160+
em = getOrCreateEntityManager();
161+
em.getTransaction().begin();
162+
List results = em.createNativeQuery(
163+
"select p.id, p.p_name from person p order by p.p_name",
164+
"person-id-and-name"
165+
).getResultList();
166+
assertEquals( 1, results.size() );
167+
assertTyping( Person.class, results.get( 0 ) );
168+
em.getTransaction().commit();
169+
em.close();
170+
171+
em = getOrCreateEntityManager();
172+
em.getTransaction().begin();
173+
em.createQuery( "delete from Person" ).executeUpdate();
174+
em.getTransaction().commit();
175+
em.close();
176+
}
177+
178+
179+
@Test
180+
public void testMultipleConstructorResultNativeQuery() {
181+
EntityManager em = getOrCreateEntityManager();
182+
em.getTransaction().begin();
183+
em.persist( new Person( 1, "John", new Date() ) );
184+
em.getTransaction().commit();
185+
em.close();
186+
187+
em = getOrCreateEntityManager();
188+
em.getTransaction().begin();
189+
List results = em.createNamedQuery( "person-id-and-name2" ).getResultList();
190+
assertEquals( 1, results.size() );
191+
Object[] result = assertTyping( Object[].class, results.get( 0 ) );
192+
assertEquals( 2, result.length );
193+
assertTyping( Person.class, result[0] );
194+
assertTyping( Person.class, result[1] );
195+
em.getTransaction().commit();
196+
em.close();
197+
198+
em = getOrCreateEntityManager();
199+
em.getTransaction().begin();
200+
em.createQuery( "delete from Person" ).executeUpdate();
201+
em.getTransaction().commit();
202+
em.close();
203+
}
204+
205+
@Test
206+
public void testConstructorResultNativeQuerySpecifyingType() {
207+
EntityManager em = getOrCreateEntityManager();
208+
em.getTransaction().begin();
209+
em.persist( new Person( 1, "John", "85" ) );
210+
em.getTransaction().commit();
211+
em.close();
212+
213+
em = getOrCreateEntityManager();
214+
em.getTransaction().begin();
215+
List results = em.createNamedQuery( "person-id-and-name-and-weight" ).getResultList();
216+
assertEquals( 1, results.size() );
217+
assertTyping( Person.class, results.get( 0 ) );
218+
em.getTransaction().commit();
219+
em.close();
220+
221+
em = getOrCreateEntityManager();
222+
em.getTransaction().begin();
223+
em.createQuery( "delete from Person" ).executeUpdate();
224+
em.getTransaction().commit();
225+
em.close();
226+
}
227+
}

0 commit comments

Comments
 (0)