Skip to content

Commit a3c779a

Browse files
dreab8sebersole
authored andcommitted
HHH-18302 Add test for issue
1 parent 8766a8e commit a3c779a

File tree

2 files changed

+169
-7
lines changed

2 files changed

+169
-7
lines changed

hibernate-core/src/test/java/org/hibernate/orm/test/procedure/DB2StoredProcedureTest.java

Lines changed: 166 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -28,19 +28,27 @@
2828
import org.hibernate.testing.orm.junit.Jira;
2929
import org.hibernate.testing.orm.junit.Jpa;
3030
import org.hibernate.testing.orm.junit.RequiresDialect;
31+
import org.hibernate.testing.orm.junit.SessionFactoryScope;
3132
import org.junit.jupiter.api.AfterAll;
33+
import org.junit.jupiter.api.AfterEach;
34+
import org.junit.jupiter.api.Assertions;
3235
import org.junit.jupiter.api.BeforeAll;
36+
import org.junit.jupiter.api.BeforeEach;
3337
import org.junit.jupiter.api.Test;
3438

39+
import jakarta.persistence.Column;
3540
import jakarta.persistence.Entity;
3641
import jakarta.persistence.Id;
3742
import jakarta.persistence.NamedStoredProcedureQueries;
3843
import jakarta.persistence.NamedStoredProcedureQuery;
3944
import jakarta.persistence.ParameterMode;
4045
import jakarta.persistence.StoredProcedureParameter;
4146
import jakarta.persistence.StoredProcedureQuery;
47+
import jakarta.persistence.Table;
48+
import org.hamcrest.MatcherAssert;
4249

4350
import static org.assertj.core.api.Assertions.assertThat;
51+
import static org.hamcrest.core.Is.is;
4452
import static org.junit.jupiter.api.Assertions.assertEquals;
4553
import static org.junit.jupiter.api.Assertions.assertFalse;
4654
import static org.junit.jupiter.api.Assertions.assertNotNull;
@@ -55,10 +63,16 @@
5563
Phone.class,
5664
Vote.class,
5765
DB2StoredProcedureTest.IdHolder.class,
66+
DB2StoredProcedureTest.Address.class,
5867
} )
5968
@RequiresDialect( value = DB2Dialect.class )
6069
@Jira( "https://hibernate.atlassian.net/browse/HHH-18332" )
6170
public class DB2StoredProcedureTest {
71+
72+
private static final String CITY = "London";
73+
private static final String STREET = "Lollard Street";
74+
private static final String ZIP = "SE116U";
75+
6276
@Test
6377
public void testStoredProcedureOutParameter(EntityManagerFactoryScope scope) {
6478
scope.inTransaction( entityManager -> {
@@ -242,6 +256,88 @@ public void testBindParameterAsHibernateType(EntityManagerFactoryScope scope) {
242256
} );
243257
}
244258

259+
@Test
260+
@Jira( "https://hibernate.atlassian.net/browse/HHH-18302" )
261+
public void testStoredProcedureInAndOutAndRefCursorParameters(EntityManagerFactoryScope scope) {
262+
scope.inTransaction(
263+
entityManager -> {
264+
StoredProcedureQuery query = entityManager.createStoredProcedureQuery( "sp_get_address_by_street_city" );
265+
query.registerStoredProcedureParameter( "street_in", String.class, ParameterMode.IN );
266+
query.registerStoredProcedureParameter( "city_in", String.class, ParameterMode.IN );
267+
query.registerStoredProcedureParameter( "rec_out", ResultSet.class, ParameterMode.REF_CURSOR );
268+
269+
query.setParameter( "street_in", STREET )
270+
.setParameter( "city_in", CITY );
271+
query.execute();
272+
ResultSet rs = (ResultSet) query.getOutputParameterValue( "rec_out" );
273+
try {
274+
Assertions.assertTrue( rs.next() );
275+
MatcherAssert.assertThat( rs.getString( "street" ), is( STREET ) );
276+
MatcherAssert.assertThat( rs.getString( "city" ), is( CITY ) );
277+
MatcherAssert.assertThat( rs.getString( "zip" ), is( ZIP ) );
278+
}
279+
catch (SQLException e) {
280+
throw new RuntimeException( e );
281+
}
282+
}
283+
);
284+
}
285+
286+
@Test
287+
@Jira( "https://hibernate.atlassian.net/browse/HHH-18302" )
288+
public void testStoredProcedureInAndOutAndRefCursorParametersDifferentRegistrationOrder(EntityManagerFactoryScope scope) {
289+
scope.inTransaction(
290+
entityManager -> {
291+
StoredProcedureQuery query = entityManager.createStoredProcedureQuery( "sp_get_address_by_street_city" );
292+
query.registerStoredProcedureParameter( "city_in", String.class, ParameterMode.IN );
293+
query.registerStoredProcedureParameter( "street_in", String.class, ParameterMode.IN );
294+
query.registerStoredProcedureParameter( "rec_out", ResultSet.class, ParameterMode.REF_CURSOR );
295+
296+
query.setParameter( "street_in", STREET )
297+
.setParameter( "city_in", CITY );
298+
query.execute();
299+
ResultSet rs = (ResultSet) query.getOutputParameterValue( "rec_out" );
300+
try {
301+
Assertions.assertTrue( rs.next() );
302+
MatcherAssert.assertThat( rs.getString( "street" ), is( STREET ) );
303+
MatcherAssert.assertThat( rs.getString( "city" ), is( CITY ) );
304+
MatcherAssert.assertThat( rs.getString( "zip" ), is( ZIP ) );
305+
}
306+
catch (SQLException e) {
307+
throw new RuntimeException( e );
308+
}
309+
}
310+
);
311+
}
312+
313+
@Test
314+
@Jira( "https://hibernate.atlassian.net/browse/HHH-18302" )
315+
public void testStoredProcedureInAndOutAndRefCursorParametersDifferentRegistrationOrder2(EntityManagerFactoryScope scope) {
316+
scope.inTransaction(
317+
entityManager -> {
318+
StoredProcedureQuery query = entityManager.createStoredProcedureQuery( "sp_get_address_by_street_city" );
319+
query.registerStoredProcedureParameter( "rec_out", ResultSet.class, ParameterMode.REF_CURSOR );
320+
query.registerStoredProcedureParameter( "city_in", String.class, ParameterMode.IN );
321+
query.registerStoredProcedureParameter( "street_in", String.class, ParameterMode.IN );
322+
323+
query.setParameter( "street_in", STREET )
324+
.setParameter( "city_in", CITY );
325+
query.execute();
326+
ResultSet rs = (ResultSet) query.getOutputParameterValue( "rec_out" );
327+
try {
328+
Assertions.assertTrue( rs.next() );
329+
MatcherAssert.assertThat( rs.getString( "street" ), is( STREET ) );
330+
MatcherAssert.assertThat( rs.getString( "city" ), is( CITY ) );
331+
MatcherAssert.assertThat( rs.getString( "zip" ), is( ZIP ) );
332+
}
333+
catch (SQLException e) {
334+
throw new RuntimeException( e );
335+
}
336+
}
337+
);
338+
}
339+
340+
245341
@BeforeAll
246342
public void prepareSchema(EntityManagerFactoryScope scope) {
247343
scope.inTransaction( (entityManager) -> entityManager.unwrap( Session.class ).doWork( (connection) -> {
@@ -355,9 +451,27 @@ public void prepareSchema(EntityManagerFactoryScope scope) {
355451
" OPEN votes; " +
356452
"END"
357453
);
454+
statement.executeUpdate(
455+
"CREATE OR REPLACE PROCEDURE sp_get_address_by_street_city ( " +
456+
" IN street_in VARCHAR(255), " +
457+
" IN city_in VARCHAR(255), " +
458+
" OUT rec_out CURSOR ) " +
459+
"BEGIN " +
460+
" SET rec_out = CURSOR FOR " +
461+
" SELECT * " +
462+
" FROM ADDRESS_TABLE A " +
463+
" WHERE " +
464+
" A.STREET = street_in" +
465+
" AND A.CITY = city_in;" +
466+
" OPEN rec_out; " +
467+
"END;"
468+
);
358469
}
359470
} ) );
471+
}
360472

473+
@BeforeEach
474+
public void setUp(EntityManagerFactoryScope scope){
361475
scope.inTransaction( (entityManager) -> {
362476
final Person person1 = new Person( 1L, "John Doe" );
363477
person1.setNickName( "JD" );
@@ -377,6 +491,8 @@ public void prepareSchema(EntityManagerFactoryScope scope) {
377491
phone2.setValid( false );
378492

379493
person1.addPhone( phone2 );
494+
Address address = new Address( 1l, STREET, CITY, ZIP );
495+
entityManager.persist( address );
380496
} );
381497
}
382498

@@ -394,15 +510,21 @@ public void cleanUpSchema(EntityManagerFactoryScope scope) {
394510
statement.executeUpdate( "DROP PROCEDURE outAndRefCursor" );
395511
statement.executeUpdate( "DROP PROCEDURE sp_phone_validity" );
396512
statement.executeUpdate( "DROP PROCEDURE sp_votes" );
513+
statement.executeUpdate( "DROP PROCEDURE sp_get_address_by_street_city" );
397514
}
398515
catch (final SQLException ignore) {
399516
}
400517
} );
518+
} );
519+
}
401520

402-
scope.inTransaction( em, (em2) -> {
403-
final List<Person> people = em.createQuery( "from Person", Person.class ).getResultList();
404-
people.forEach( em::remove );
405-
} );
521+
@AfterEach
522+
public void cleanData(EntityManagerFactoryScope scope) {
523+
scope.inTransaction( (em) -> {
524+
final List<Person> people = em.createQuery( "from Person", Person.class ).getResultList();
525+
people.forEach( em::remove );
526+
527+
em.createQuery( "delete Address" ).executeUpdate();
406528
} );
407529
}
408530

@@ -429,4 +551,44 @@ public static class IdHolder {
429551
Long id;
430552
String name;
431553
}
554+
555+
@Entity(name = "Address")
556+
@Table(name = "ADDRESS_TABLE")
557+
public static class Address {
558+
@Id
559+
@Column(name = "ID")
560+
private long id;
561+
@Column(name = "STREET")
562+
private String street;
563+
@Column(name = "CITY")
564+
private String city;
565+
@Column(name = "ZIP")
566+
private String zip;
567+
568+
public Address() {
569+
}
570+
571+
public Address(long id, String street, String city, String zip) {
572+
this.id = id;
573+
this.street = street;
574+
this.city = city;
575+
this.zip = zip;
576+
}
577+
578+
public long getId() {
579+
return id;
580+
}
581+
582+
public String getStreet() {
583+
return street;
584+
}
585+
586+
public String getCity() {
587+
return city;
588+
}
589+
590+
public String getZip() {
591+
return zip;
592+
}
593+
}
432594
}

hibernate-core/src/test/resources/org/hibernate/orm/test/sql/hand/custom/db2/Mappings.hbm.xml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -186,7 +186,7 @@
186186
<sql-query name="simpleScalar" callable="true">
187187
<return-scalar column="name" type="string"/>
188188
<return-scalar column="`value`" type="long"/>
189-
{ call simpleScalar(:number) }
189+
{ call simpleScalar(:p_number) }
190190
</sql-query>
191191

192192
<sql-query name="paramhandling" callable="true">
@@ -261,10 +261,10 @@
261261

262262
<database-object>
263263
<create>
264-
CREATE PROCEDURE simpleScalar (IN j SMALLINT) RESULT SETS 1
264+
CREATE PROCEDURE simpleScalar (IN p_number SMALLINT) RESULT SETS 1
265265
P1: BEGIN
266266
DECLARE C1 CURSOR WITH RETURN FOR
267-
SELECT j as value, 'getAll' as name from sysibm.sysdummy1;
267+
SELECT p_number as value, 'getAll' as name from sysibm.sysdummy1;
268268
OPEN C1;
269269
END P1
270270
</create>

0 commit comments

Comments
 (0)