diff --git a/hibernate-core/src/test/java/org/hibernate/test/procedure/HANAStoredProcedureTest.java b/hibernate-core/src/test/java/org/hibernate/test/procedure/HANAStoredProcedureTest.java index c751ca71a4..324ac824f5 100644 --- a/hibernate-core/src/test/java/org/hibernate/test/procedure/HANAStoredProcedureTest.java +++ b/hibernate-core/src/test/java/org/hibernate/test/procedure/HANAStoredProcedureTest.java @@ -37,6 +37,8 @@ import org.hibernate.result.Output; import org.hibernate.result.ResultSetOutput; import org.hibernate.testing.RequiresDialect; import org.hibernate.testing.TestForIssue; +import org.hibernate.type.NumericBooleanType; +import org.hibernate.type.YesNoType; import org.junit.After; import org.junit.Before; import org.junit.Test; @@ -52,7 +54,8 @@ public class HANAStoredProcedureTest extends BaseEntityManagerFunctionalTestCase return new Class[]{ Person.class, Phone.class, - IdHolder.class + IdHolder.class, + Vote.class }; } @@ -126,7 +129,8 @@ public class HANAStoredProcedureTest extends BaseEntityManagerFunctionalTestCase + " \"pr.version\" INTEGER," + " \"ph.id\" BIGINT," + " \"ph.person_id\" BIGINT," - + " \"ph.phone_number\" NVARCHAR(5000)) " + + + " \"ph.phone_number\" NVARCHAR(5000)," + + " \"ph.valid\" BOOLEAN)" + "AS " + "BEGIN " + " RETURN " + @@ -139,7 +143,8 @@ public class HANAStoredProcedureTest extends BaseEntityManagerFunctionalTestCase " pr.version AS \"pr.version\", " + " ph.id AS \"ph.id\", " + " ph.person_id AS \"ph.person_id\", " + - " ph.phone_number AS \"ph.phone_number\" " + + " ph.phone_number AS \"ph.phone_number\", " + + " ph.valid AS \"ph.valid\" " + " FROM person pr " + " JOIN phone ph ON pr.id = ph.person_id " + " WHERE pr.id = personId; " + @@ -161,6 +166,26 @@ public class HANAStoredProcedureTest extends BaseEntityManagerFunctionalTestCase " FROM SYS.DUMMY; " + " SELECT 1 INTO p_value FROM SYS.DUMMY; " + " END; " ); + statement.executeUpdate( + "CREATE OR REPLACE PROCEDURE sp_phone_validity ( " + + " IN validity BOOLEAN, " + + " OUT personPhones TABLE (\"phone_number\" VARCHAR(255)) ) " + + "AS " + + "BEGIN " + + " personPhones = SELECT phone_number as \"phone_number\" " + + " FROM phone " + + " WHERE valid = validity; " + + "END;" ); + statement.executeUpdate( + "CREATE OR REPLACE PROCEDURE sp_votes ( " + + " IN validity VARCHAR(1), " + + " OUT votes TABLE (\"id\" BIGINT) ) " + + "AS " + + "BEGIN " + + " votes = SELECT id as \"id\" " + + " FROM vote " + + " WHERE vote_choice = validity; " + + "END;" ); } finally { if ( statement != null ) { @@ -187,11 +212,13 @@ public class HANAStoredProcedureTest extends BaseEntityManagerFunctionalTestCase Phone phone1 = new Phone( "123-456-7890" ); phone1.setId( 1L ); + phone1.setValid( true ); person1.addPhone( phone1 ); Phone phone2 = new Phone( "098_765-4321" ); phone2.setId( 2L ); + phone2.setValid( false ); person1.addPhone( phone2 ); @@ -467,4 +494,47 @@ public class HANAStoredProcedureTest extends BaseEntityManagerFunctionalTestCase assertFalse( function.hasMoreResults() ); } ); } + + @Test + @TestForIssue(jiraKey = "HHH-12661") + public void testBindParameterAsHibernateType() { + + doInJPA( this::entityManagerFactory, entityManager -> { + StoredProcedureQuery query = entityManager.createStoredProcedureQuery( "sp_phone_validity" ) + .registerStoredProcedureParameter( 1, NumericBooleanType.class, ParameterMode.IN ) + .registerStoredProcedureParameter( 2, Class.class, ParameterMode.REF_CURSOR ) + .setParameter( 1, true ); + + query.execute(); + List phones = query.getResultList(); + assertEquals( 1, phones.size() ); + assertEquals( "123-456-7890", phones.get( 0 ) ); + } ); + + doInJPA( this::entityManagerFactory, entityManager -> { + Vote vote1 = new Vote(); + vote1.setId( 1L ); + vote1.setVoteChoice( true ); + + entityManager.persist( vote1 ); + + Vote vote2 = new Vote(); + vote2.setId( 2L ); + vote2.setVoteChoice( false ); + + entityManager.persist( vote2 ); + } ); + + doInJPA( this::entityManagerFactory, entityManager -> { + StoredProcedureQuery query = entityManager.createStoredProcedureQuery( "sp_votes" ) + .registerStoredProcedureParameter( 1, YesNoType.class, ParameterMode.IN ) + .registerStoredProcedureParameter( 2, Class.class, ParameterMode.REF_CURSOR ) + .setParameter( 1, true ); + + query.execute(); + List votes = query.getResultList(); + assertEquals( 1, votes.size() ); + assertEquals( 1, ( (Number) votes.get( 0 ) ).intValue() ); + } ); + } } diff --git a/hibernate-core/src/test/java/org/hibernate/test/procedure/OracleStoredProcedureTest.java b/hibernate-core/src/test/java/org/hibernate/test/procedure/OracleStoredProcedureTest.java index 6421c233ae..1d4434ef40 100644 --- a/hibernate-core/src/test/java/org/hibernate/test/procedure/OracleStoredProcedureTest.java +++ b/hibernate-core/src/test/java/org/hibernate/test/procedure/OracleStoredProcedureTest.java @@ -156,7 +156,8 @@ public class OracleStoredProcedureTest extends BaseEntityManagerFunctionalTestCa " pr.version AS \"pr.version\", " + " ph.id AS \"ph.id\", " + " ph.person_id AS \"ph.person_id\", " + - " ph.phone_number AS \"ph.phone_number\" " + + " ph.phone_number AS \"ph.phone_number\", " + + " ph.valid AS \"ph.valid\" " + " FROM person pr " + " JOIN phone ph ON pr.id = ph.person_id " + " WHERE pr.id = personId; " + diff --git a/hibernate-core/src/test/java/org/hibernate/test/procedure/Person.java b/hibernate-core/src/test/java/org/hibernate/test/procedure/Person.java index 195c9a36f3..703b909419 100644 --- a/hibernate-core/src/test/java/org/hibernate/test/procedure/Person.java +++ b/hibernate-core/src/test/java/org/hibernate/test/procedure/Person.java @@ -36,9 +36,9 @@ import org.hibernate.annotations.NamedNativeQuery; ) @NamedNativeQuery( name = "fn_person_and_phones_hana", - query = "select * from fn_person_and_phones( ? )", + query = "select \"pr.id\", \"pr.name\", \"pr.nickName\", \"pr.address\", \"pr.createdOn\", \"pr.version\", \"ph.id\", \"ph.person_id\", \"ph.phone_number\", \"ph.valid\" from fn_person_and_phones( ? )", callable = false, - resultSetMapping = "person_with_phones" + resultSetMapping = "person_with_phones_hana" ) @SqlResultSetMappings({ @SqlResultSetMapping( @@ -60,7 +60,33 @@ import org.hibernate.annotations.NamedNativeQuery; fields = { @FieldResult( name = "id", column = "ph.id" ), @FieldResult( name = "person", column = "ph.person_id" ), - @FieldResult( name = "number", column = "ph.phone_number" ) + @FieldResult( name = "number", column = "ph.phone_number" ), + @FieldResult( name = "valid", column = "ph.valid" ) + } + ) + } + ), + @SqlResultSetMapping( + name = "person_with_phones_hana", + entities = { + @EntityResult( + entityClass = Person.class, + fields = { + @FieldResult( name = "id", column = "pr.id" ), + @FieldResult( name = "name", column = "pr.name" ), + @FieldResult( name = "nickName", column = "pr.nickName" ), + @FieldResult( name = "address", column = "pr.address" ), + @FieldResult( name = "createdOn", column = "pr.createdOn" ), + @FieldResult( name = "version", column = "pr.version" ), + } + ), + @EntityResult( + entityClass = Phone.class, + fields = { + @FieldResult( name = "id", column = "ph.id" ), + @FieldResult( name = "person", column = "ph.person_id" ), + @FieldResult( name = "number", column = "ph.phone_number" ), + @FieldResult( name = "valid", column = "ph.valid" ) } ) }