From cc1ffbaaa066df990d34aea6cb4ae59f3bbfbaf4 Mon Sep 17 00:00:00 2001 From: Roland Kurucz Date: Sat, 11 Aug 2018 20:27:51 +0200 Subject: [PATCH] HHH-12905 - Bind value [null] was not of specified type in StoredProcedureQuery --- .../procedure/internal/ParameterBindImpl.java | 15 +- .../procedure/MySQLStoredProcedureTest.java | 83 ++++++++ .../PostgreSQLStoredProcedureTest.java | 184 +++++++++++++----- .../StoredProcedureParameterTypeTest.java | 67 ++++++- 4 files changed, 297 insertions(+), 52 deletions(-) diff --git a/hibernate-core/src/main/java/org/hibernate/procedure/internal/ParameterBindImpl.java b/hibernate-core/src/main/java/org/hibernate/procedure/internal/ParameterBindImpl.java index 4d9dd0b860..6b7d99bb51 100644 --- a/hibernate-core/src/main/java/org/hibernate/procedure/internal/ParameterBindImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/procedure/internal/ParameterBindImpl.java @@ -79,8 +79,19 @@ public class ParameterBindImpl implements ParameterBind { } if ( procedureParameter.getParameterType() != null ) { - if ( !procedureParameter.getParameterType().isInstance( value ) && !procedureParameter.getHibernateType().getReturnedClass().isInstance( value ) ) { - throw new IllegalArgumentException( "Bind value [" + value + "] was not of specified type [" + procedureParameter.getParameterType() ); + if ( value == null ) { + if ( !procedureParameter.isPassNullsEnabled() ) { + throw new IllegalArgumentException( "The parameter with the [" + + ( procedureParameter.getName() != null + ? procedureParameter.getName() + "] name" + : procedureParameter.getPosition() + "] position" ) + + " was null. You need to call ParameterRegistration#enablePassingNulls(true) in order to pass null parameters." ); + } + } + else if ( !procedureParameter.getParameterType().isInstance( value ) && + !procedureParameter.getHibernateType().getReturnedClass().isInstance( value ) ) { + throw new IllegalArgumentException( "Bind value [" + value + "] was not of specified type [" + procedureParameter + .getParameterType() ); } } diff --git a/hibernate-core/src/test/java/org/hibernate/test/procedure/MySQLStoredProcedureTest.java b/hibernate-core/src/test/java/org/hibernate/test/procedure/MySQLStoredProcedureTest.java index cd231086c0..4e55459054 100644 --- a/hibernate-core/src/test/java/org/hibernate/test/procedure/MySQLStoredProcedureTest.java +++ b/hibernate-core/src/test/java/org/hibernate/test/procedure/MySQLStoredProcedureTest.java @@ -28,14 +28,19 @@ import org.hibernate.jpa.test.BaseEntityManagerFunctionalTestCase; import org.hibernate.procedure.ProcedureCall; import org.hibernate.result.Output; import org.hibernate.result.ResultSetOutput; +import org.hibernate.type.StringType; import org.hibernate.testing.RequiresDialect; +import org.hibernate.testing.TestForIssue; import org.junit.After; import org.junit.Before; import org.junit.Test; +import static org.hibernate.testing.transaction.TransactionUtil.doInJPA; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; /** * @author Vlad Mihalcea @@ -98,6 +103,18 @@ public class MySQLStoredProcedureTest extends BaseEntityManagerFunctionalTestCas " RETURN phoneCount; " + "END" ); + + statement.executeUpdate( + "CREATE PROCEDURE sp_is_null (" + + " IN param varchar(255), " + + " OUT result BIT(1) " + + ") " + + "BEGIN " + + " IF (param IS NULL) THEN SET result = 1; " + + " ELSE SET result = 0; " + + " END IF; " + + "END" + ); } finally { if ( statement != null ) { statement.close(); @@ -193,6 +210,24 @@ public class MySQLStoredProcedureTest extends BaseEntityManagerFunctionalTestCas entityManager.getTransaction().rollback(); entityManager.close(); } + + entityManager = createEntityManager(); + entityManager.getTransaction().begin(); + + try { + Session session = entityManager.unwrap( Session.class ); + session.doWork( connection -> { + try (Statement statement = connection.createStatement()) { + statement.executeUpdate( "DROP PROCEDURE IF EXISTS sp_is_null" ); + } + catch (SQLException ignore) { + } + } ); + } + finally { + entityManager.getTransaction().rollback(); + entityManager.close(); + } } @Test @@ -332,4 +367,52 @@ public class MySQLStoredProcedureTest extends BaseEntityManagerFunctionalTestCas entityManager.close(); } } + + @Test + @TestForIssue( jiraKey = "HHH-12905") + public void testStoredProcedureNullParameter() { + + doInJPA( this::entityManagerFactory, entityManager -> { + ProcedureCall procedureCall = entityManager.unwrap( Session.class ).createStoredProcedureCall("sp_is_null"); + procedureCall.registerParameter( 1, StringType.class, ParameterMode.IN).enablePassingNulls( true); + procedureCall.registerParameter( 2, Boolean.class, ParameterMode.OUT); + procedureCall.setParameter(1, null); + + Boolean result = (Boolean) procedureCall.getOutputParameterValue( 2 ); + + assertTrue( result ); + }); + + doInJPA( this::entityManagerFactory, entityManager -> { + ProcedureCall procedureCall = entityManager.unwrap( Session.class ).createStoredProcedureCall("sp_is_null"); + procedureCall.registerParameter( 1, StringType.class, ParameterMode.IN).enablePassingNulls( true); + procedureCall.registerParameter( 2, Boolean.class, ParameterMode.OUT); + procedureCall.setParameter(1, "test"); + + Boolean result = (Boolean) procedureCall.getOutputParameterValue( 2 ); + + assertFalse( result ); + }); + } + + @Test + @TestForIssue( jiraKey = "HHH-12905") + public void testStoredProcedureNullParameterHibernateWithoutEnablePassingNulls() { + + doInJPA( this::entityManagerFactory, entityManager -> { + try { + ProcedureCall procedureCall = entityManager.unwrap( Session.class ).createStoredProcedureCall("sp_is_null"); + procedureCall.registerParameter( 1, StringType.class, ParameterMode.IN); + procedureCall.registerParameter( 2, Boolean.class, ParameterMode.OUT); + procedureCall.setParameter(1, null); + + procedureCall.getOutputParameterValue( 2 ); + + fail("Should have thrown exception"); + } + catch (IllegalArgumentException e) { + assertEquals( "The parameter on the [1] position was null. You need to call ParameterRegistration#enablePassingNulls in order to pass null parameters.", e.getMessage() ); + } + }); + } } diff --git a/hibernate-core/src/test/java/org/hibernate/test/procedure/PostgreSQLStoredProcedureTest.java b/hibernate-core/src/test/java/org/hibernate/test/procedure/PostgreSQLStoredProcedureTest.java index 0515969d21..73a7e77f4c 100644 --- a/hibernate-core/src/test/java/org/hibernate/test/procedure/PostgreSQLStoredProcedureTest.java +++ b/hibernate-core/src/test/java/org/hibernate/test/procedure/PostgreSQLStoredProcedureTest.java @@ -16,12 +16,16 @@ import java.sql.Types; import java.time.LocalDateTime; import java.time.ZoneOffset; import java.util.List; +import java.util.Properties; import javax.persistence.ParameterMode; import javax.persistence.StoredProcedureQuery; import org.hibernate.Session; +import org.hibernate.cfg.AvailableSettings; import org.hibernate.dialect.PostgreSQL81Dialect; import org.hibernate.jpa.test.BaseEntityManagerFunctionalTestCase; +import org.hibernate.procedure.ProcedureCall; +import org.hibernate.type.StringType; import org.hibernate.testing.RequiresDialect; import org.hibernate.testing.TestForIssue; @@ -31,6 +35,7 @@ import org.junit.Test; import static org.hibernate.testing.transaction.TransactionUtil.doInJPA; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; /** @@ -42,8 +47,8 @@ public class PostgreSQLStoredProcedureTest extends BaseEntityManagerFunctionalTe @Override protected Class[] getAnnotatedClasses() { return new Class[] { - Person.class, - Phone.class + Person.class, + Phone.class }; } @@ -106,6 +111,25 @@ public class PostgreSQLStoredProcedureTest extends BaseEntityManagerFunctionalTe } ); } ); + doInJPA( this::entityManagerFactory, entityManager -> { + Session session = entityManager.unwrap( Session.class ); + + session.doWork( connection -> { + Statement statement = null; + try { + statement = connection.createStatement(); + statement.executeUpdate( "DROP FUNCTION sp_is_null()" ); + } + catch (SQLException ignore) { + } + finally { + if ( statement != null ) { + statement.close(); + } + } + } ); + } ); + doInJPA( this::entityManagerFactory, entityManager -> { Session session = entityManager.unwrap( Session.class ); @@ -114,49 +138,62 @@ public class PostgreSQLStoredProcedureTest extends BaseEntityManagerFunctionalTe try { statement = connection.createStatement(); statement.executeUpdate( - "CREATE OR REPLACE FUNCTION sp_count_phones( " + - " IN personId bigint, " + - " OUT phoneCount bigint) " + - " RETURNS bigint AS " + - "$BODY$ " + - " BEGIN " + - " SELECT COUNT(*) INTO phoneCount " + - " FROM phone " + - " WHERE person_id = personId; " + - " END; " + - "$BODY$ " + - "LANGUAGE plpgsql;" + "CREATE OR REPLACE FUNCTION sp_count_phones( " + + " IN personId bigint, " + + " OUT phoneCount bigint) " + + " RETURNS bigint AS " + + "$BODY$ " + + " BEGIN " + + " SELECT COUNT(*) INTO phoneCount " + + " FROM phone " + + " WHERE person_id = personId; " + + " END; " + + "$BODY$ " + + "LANGUAGE plpgsql;" ); statement.executeUpdate( - "CREATE OR REPLACE FUNCTION fn_phones(personId BIGINT) " + - " RETURNS REFCURSOR AS " + - "$BODY$ " + - " DECLARE " + - " phones REFCURSOR; " + - " BEGIN " + - " OPEN phones FOR " + - " SELECT * " + - " FROM phone " + - " WHERE person_id = personId; " + - " RETURN phones; " + - " END; " + - "$BODY$ " + - "LANGUAGE plpgsql" + "CREATE OR REPLACE FUNCTION fn_phones(personId BIGINT) " + + " RETURNS REFCURSOR AS " + + "$BODY$ " + + " DECLARE " + + " phones REFCURSOR; " + + " BEGIN " + + " OPEN phones FOR " + + " SELECT * " + + " FROM phone " + + " WHERE person_id = personId; " + + " RETURN phones; " + + " END; " + + "$BODY$ " + + "LANGUAGE plpgsql" ); statement.executeUpdate( - "CREATE OR REPLACE FUNCTION singleRefCursor() " + - " RETURNS REFCURSOR AS " + - "$BODY$ " + - " DECLARE " + - " p_recordset REFCURSOR; " + - " BEGIN " + - " OPEN p_recordset FOR SELECT 1; " + - " RETURN p_recordset; " + - " END; " + - "$BODY$ " + - "LANGUAGE plpgsql;" + "CREATE OR REPLACE FUNCTION singleRefCursor() " + + " RETURNS REFCURSOR AS " + + "$BODY$ " + + " DECLARE " + + " p_recordset REFCURSOR; " + + " BEGIN " + + " OPEN p_recordset FOR SELECT 1; " + + " RETURN p_recordset; " + + " END; " + + "$BODY$ " + + "LANGUAGE plpgsql;" + ); + + statement.executeUpdate( + "CREATE OR REPLACE FUNCTION sp_is_null( " + + " IN param varchar(255), " + + " OUT result boolean) " + + " RETURNS boolean AS " + + "$BODY$ " + + " BEGIN " + + " select param is null into result; " + + " END; " + + "$BODY$ " + + "LANGUAGE plpgsql;" ); } finally { @@ -171,7 +208,8 @@ public class PostgreSQLStoredProcedureTest extends BaseEntityManagerFunctionalTe Person person1 = new Person( "John Doe" ); person1.setNickName( "JD" ); person1.setAddress( "Earth" ); - person1.setCreatedOn( Timestamp.from( LocalDateTime.of( 2000, 1, 1, 0, 0, 0 ).toInstant( ZoneOffset.UTC ) ) ); + person1.setCreatedOn( Timestamp.from( LocalDateTime.of( 2000, 1, 1, 0, 0, 0 ) + .toInstant( ZoneOffset.UTC ) ) ); entityManager.persist( person1 ); @@ -185,7 +223,7 @@ public class PostgreSQLStoredProcedureTest extends BaseEntityManagerFunctionalTe person1.addPhone( phone2 ); } ); - } + } @Test public void testStoredProcedureOutParameter() { @@ -260,14 +298,15 @@ public class PostgreSQLStoredProcedureTest extends BaseEntityManagerFunctionalTe } } ); assertEquals( Long.valueOf( 2 ), phoneCount ); - } catch (Exception e) { + } + catch (Exception e) { assertEquals( SQLFeatureNotSupportedException.class, e.getCause().getClass() ); } } ); } @Test - @TestForIssue( jiraKey = "HHH-11863") + @TestForIssue(jiraKey = "HHH-11863") public void testSysRefCursorAsOutParameter() { doInJPA( this::entityManagerFactory, entityManager -> { @@ -275,7 +314,7 @@ public class PostgreSQLStoredProcedureTest extends BaseEntityManagerFunctionalTe Session session = entityManager.unwrap( Session.class ); - try(ResultSet resultSet = session.doReturningWork( connection -> { + try (ResultSet resultSet = session.doReturningWork( connection -> { CallableStatement function = null; try { function = connection.prepareCall( "{ ? = call singleRefCursor() }" ); @@ -294,7 +333,7 @@ public class PostgreSQLStoredProcedureTest extends BaseEntityManagerFunctionalTe } } catch (Exception e) { - fail(e.getMessage()); + fail( e.getMessage() ); } assertEquals( Long.valueOf( 1 ), value ); @@ -307,16 +346,67 @@ public class PostgreSQLStoredProcedureTest extends BaseEntityManagerFunctionalTe assertFalse( function.hasMoreResults() ); value = null; - try ( ResultSet resultSet = (ResultSet) function.getOutputParameterValue( 1 ) ) { + try (ResultSet resultSet = (ResultSet) function.getOutputParameterValue( 1 )) { while ( resultSet.next() ) { value = resultSet.getLong( 1 ); } } catch (SQLException e) { - fail(e.getMessage()); + fail( e.getMessage() ); } assertEquals( Long.valueOf( 1 ), value ); } ); } + + @Test + @TestForIssue(jiraKey = "HHH-12905") + public void testStoredProcedureNullParameterHibernate() { + + doInJPA( this::entityManagerFactory, entityManager -> { + ProcedureCall procedureCall = entityManager.unwrap( Session.class ) + .createStoredProcedureCall( "sp_is_null" ); + procedureCall.registerParameter( 1, StringType.class, ParameterMode.IN ).enablePassingNulls( true ); + procedureCall.registerParameter( 2, Boolean.class, ParameterMode.OUT ); + procedureCall.setParameter( 1, null ); + + Boolean result = (Boolean) procedureCall.getOutputParameterValue( 2 ); + + assertTrue( result ); + } ); + + doInJPA( this::entityManagerFactory, entityManager -> { + ProcedureCall procedureCall = entityManager.unwrap( Session.class ) + .createStoredProcedureCall( "sp_is_null" ); + procedureCall.registerParameter( 1, StringType.class, ParameterMode.IN ).enablePassingNulls( true ); + procedureCall.registerParameter( 2, Boolean.class, ParameterMode.OUT ); + procedureCall.setParameter( 1, "test" ); + + Boolean result = (Boolean) procedureCall.getOutputParameterValue( 2 ); + + assertFalse( result ); + } ); + } + + @Test + @TestForIssue(jiraKey = "HHH-12905") + public void testStoredProcedureNullParameterHibernateWithoutEnablePassingNulls() { + + doInJPA( this::entityManagerFactory, entityManager -> { + try { + ProcedureCall procedureCall = entityManager.unwrap( Session.class ) + .createStoredProcedureCall( "sp_is_null" ); + procedureCall.registerParameter( "param", StringType.class, ParameterMode.IN ); + procedureCall.registerParameter( "result", Boolean.class, ParameterMode.OUT ); + procedureCall.setParameter( "param", null ); + + procedureCall.getOutputParameterValue( "result" ); + + fail("Should have thrown exception"); + } + catch (IllegalArgumentException e) { + assertEquals( "The parameter with the [param] position was null. You need to call ParameterRegistration#enablePassingNulls in order to pass null parameters.", e.getMessage() ); + } + } ); + } } diff --git a/hibernate-core/src/test/java/org/hibernate/test/procedure/StoredProcedureParameterTypeTest.java b/hibernate-core/src/test/java/org/hibernate/test/procedure/StoredProcedureParameterTypeTest.java index e630182ac7..d02c2d5467 100644 --- a/hibernate-core/src/test/java/org/hibernate/test/procedure/StoredProcedureParameterTypeTest.java +++ b/hibernate-core/src/test/java/org/hibernate/test/procedure/StoredProcedureParameterTypeTest.java @@ -29,7 +29,7 @@ import javax.persistence.ParameterMode; import javax.sql.rowset.serial.SerialBlob; import javax.sql.rowset.serial.SerialClob; -import org.hibernate.dialect.H2Dialect; +import org.hibernate.procedure.ProcedureCall; import org.hibernate.type.BigDecimalType; import org.hibernate.type.BigIntegerType; import org.hibernate.type.BinaryType; @@ -61,17 +61,17 @@ import org.hibernate.type.UUIDBinaryType; import org.hibernate.type.UrlType; import org.hibernate.type.YesNoType; -import org.hibernate.testing.RequiresDialect; import org.hibernate.testing.TestForIssue; import org.hibernate.testing.junit4.BaseNonConfigCoreFunctionalTestCase; import org.junit.Test; import static org.hibernate.testing.transaction.TransactionUtil.doInHibernate; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; /** * @author Vlad Mihalcea */ -@TestForIssue( jiraKey = "HHH-12661" ) public class StoredProcedureParameterTypeTest extends BaseNonConfigCoreFunctionalTestCase { private static final String TEST_STRING = "test_string"; @@ -79,6 +79,7 @@ public class StoredProcedureParameterTypeTest extends BaseNonConfigCoreFunctiona private static final byte[] TEST_BYTE_ARRAY = TEST_STRING.getBytes(); @Test + @TestForIssue( jiraKey = "HHH-12661" ) public void testNumericBooleanTypeInParameter() { doInHibernate( this::sessionFactory, session -> { session.createStoredProcedureQuery( "test" ) @@ -89,6 +90,7 @@ public class StoredProcedureParameterTypeTest extends BaseNonConfigCoreFunctiona } @Test + @TestForIssue( jiraKey = "HHH-12661" ) public void testYesNoTypeInParameter() { doInHibernate( this::sessionFactory, session -> { session.createStoredProcedureQuery( "test" ) @@ -99,6 +101,7 @@ public class StoredProcedureParameterTypeTest extends BaseNonConfigCoreFunctiona } @Test + @TestForIssue( jiraKey = "HHH-12661" ) public void testStringTypeInParameter() { inTransaction( session -> session.createStoredProcedureQuery("test") @@ -108,6 +111,7 @@ public class StoredProcedureParameterTypeTest extends BaseNonConfigCoreFunctiona } @Test + @TestForIssue( jiraKey = "HHH-12661" ) public void testMaterializedClobTypeInParameter() { inTransaction( session -> session.createStoredProcedureQuery("test") @@ -117,6 +121,7 @@ public class StoredProcedureParameterTypeTest extends BaseNonConfigCoreFunctiona } @Test + @TestForIssue( jiraKey = "HHH-12661" ) public void testTextTypeInParameter() { inTransaction( session -> session.createStoredProcedureQuery("test") @@ -126,6 +131,7 @@ public class StoredProcedureParameterTypeTest extends BaseNonConfigCoreFunctiona } @Test + @TestForIssue( jiraKey = "HHH-12661" ) public void testCharacterTypeInParameter() { inTransaction( session -> session.createStoredProcedureQuery("test") @@ -135,6 +141,7 @@ public class StoredProcedureParameterTypeTest extends BaseNonConfigCoreFunctiona } @Test + @TestForIssue( jiraKey = "HHH-12661" ) public void testTrueFalseTypeInParameter() { inTransaction( session -> session.createStoredProcedureQuery("test") @@ -144,6 +151,7 @@ public class StoredProcedureParameterTypeTest extends BaseNonConfigCoreFunctiona } @Test + @TestForIssue( jiraKey = "HHH-12661" ) public void testBooleanTypeInParameter() { inTransaction( session -> session.createStoredProcedureQuery("test") @@ -153,6 +161,7 @@ public class StoredProcedureParameterTypeTest extends BaseNonConfigCoreFunctiona } @Test + @TestForIssue( jiraKey = "HHH-12661" ) public void testByteTypeInParameter() { inTransaction( session -> session.createStoredProcedureQuery("test") @@ -162,6 +171,7 @@ public class StoredProcedureParameterTypeTest extends BaseNonConfigCoreFunctiona } @Test + @TestForIssue( jiraKey = "HHH-12661" ) public void testShortTypeInParameter() { inTransaction( session -> session.createStoredProcedureQuery("test") @@ -171,6 +181,7 @@ public class StoredProcedureParameterTypeTest extends BaseNonConfigCoreFunctiona } @Test + @TestForIssue( jiraKey = "HHH-12661" ) public void testIntegerTypeInParameter() { inTransaction( session -> session.createStoredProcedureQuery("test") @@ -180,6 +191,7 @@ public class StoredProcedureParameterTypeTest extends BaseNonConfigCoreFunctiona } @Test + @TestForIssue( jiraKey = "HHH-12661" ) public void testLongTypeInParameter() { inTransaction( session -> session.createStoredProcedureQuery("test") @@ -198,6 +210,7 @@ public class StoredProcedureParameterTypeTest extends BaseNonConfigCoreFunctiona } @Test + @TestForIssue( jiraKey = "HHH-12661" ) public void testDoubleTypeInParameter() { inTransaction( session -> session.createStoredProcedureQuery("test") @@ -207,6 +220,7 @@ public class StoredProcedureParameterTypeTest extends BaseNonConfigCoreFunctiona } @Test + @TestForIssue( jiraKey = "HHH-12661" ) public void testBigIntegerTypeInParameter() { inTransaction( session -> session.createStoredProcedureQuery("test") @@ -216,6 +230,7 @@ public class StoredProcedureParameterTypeTest extends BaseNonConfigCoreFunctiona } @Test + @TestForIssue( jiraKey = "HHH-12661" ) public void testBigDecimalTypeInParameter() { inTransaction( session -> session.createStoredProcedureQuery("test") @@ -225,6 +240,7 @@ public class StoredProcedureParameterTypeTest extends BaseNonConfigCoreFunctiona } @Test + @TestForIssue( jiraKey = "HHH-12661" ) public void testTimestampTypeDateInParameter() { inTransaction( session -> session.createStoredProcedureQuery("test") @@ -234,6 +250,7 @@ public class StoredProcedureParameterTypeTest extends BaseNonConfigCoreFunctiona } @Test + @TestForIssue( jiraKey = "HHH-12661" ) public void testTimestampTypeTimestampInParameter() { inTransaction( session -> session.createStoredProcedureQuery("test") @@ -243,6 +260,7 @@ public class StoredProcedureParameterTypeTest extends BaseNonConfigCoreFunctiona } @Test + @TestForIssue( jiraKey = "HHH-12661" ) public void testTimeTypeInParameter() { inTransaction( session -> session.createStoredProcedureQuery("test") @@ -252,6 +270,7 @@ public class StoredProcedureParameterTypeTest extends BaseNonConfigCoreFunctiona } @Test + @TestForIssue( jiraKey = "HHH-12661" ) public void testDateTypeInParameter() { inTransaction( session -> session.createStoredProcedureQuery("test") @@ -261,6 +280,7 @@ public class StoredProcedureParameterTypeTest extends BaseNonConfigCoreFunctiona } @Test + @TestForIssue( jiraKey = "HHH-12661" ) public void testCalendarTypeCalendarInParameter() { inTransaction( session -> session.createStoredProcedureQuery("test") @@ -270,6 +290,7 @@ public class StoredProcedureParameterTypeTest extends BaseNonConfigCoreFunctiona } @Test + @TestForIssue( jiraKey = "HHH-12661" ) public void testCurrencyTypeInParameter() { inTransaction( session -> session.createStoredProcedureQuery("test") @@ -279,6 +300,7 @@ public class StoredProcedureParameterTypeTest extends BaseNonConfigCoreFunctiona } @Test + @TestForIssue( jiraKey = "HHH-12661" ) public void testLocaleTypeInParameter() { inTransaction( session -> session.createStoredProcedureQuery("test") @@ -288,6 +310,7 @@ public class StoredProcedureParameterTypeTest extends BaseNonConfigCoreFunctiona } @Test + @TestForIssue( jiraKey = "HHH-12661" ) public void testTimeZoneTypeInParameter() { inTransaction( session -> session.createStoredProcedureQuery("test") @@ -297,6 +320,7 @@ public class StoredProcedureParameterTypeTest extends BaseNonConfigCoreFunctiona } @Test + @TestForIssue( jiraKey = "HHH-12661" ) public void testUrlTypeInParameter() throws MalformedURLException { final URL url = new URL( "http://example.com"); inTransaction( @@ -307,6 +331,7 @@ public class StoredProcedureParameterTypeTest extends BaseNonConfigCoreFunctiona } @Test + @TestForIssue( jiraKey = "HHH-12661" ) public void testClassTypeInParameter() { inTransaction( session -> session.createStoredProcedureQuery("test") @@ -316,6 +341,7 @@ public class StoredProcedureParameterTypeTest extends BaseNonConfigCoreFunctiona } @Test + @TestForIssue( jiraKey = "HHH-12661" ) public void testBlobTypeInParameter() throws SQLException { final Blob blob = new SerialBlob( TEST_BYTE_ARRAY); inTransaction( @@ -326,6 +352,7 @@ public class StoredProcedureParameterTypeTest extends BaseNonConfigCoreFunctiona } @Test + @TestForIssue( jiraKey = "HHH-12661" ) public void testClobTypeInParameter() throws SQLException { final Clob clob = new SerialClob( TEST_CHAR_ARRAY); inTransaction( @@ -336,6 +363,7 @@ public class StoredProcedureParameterTypeTest extends BaseNonConfigCoreFunctiona } @Test + @TestForIssue( jiraKey = "HHH-12661" ) public void testBinaryTypeInParameter() { inTransaction( session -> session.createStoredProcedureQuery("test") @@ -345,6 +373,7 @@ public class StoredProcedureParameterTypeTest extends BaseNonConfigCoreFunctiona } @Test + @TestForIssue( jiraKey = "HHH-12661" ) public void testCharArrayTypeInParameter() { inTransaction( session -> session.createStoredProcedureQuery("test") @@ -354,6 +383,7 @@ public class StoredProcedureParameterTypeTest extends BaseNonConfigCoreFunctiona } @Test + @TestForIssue( jiraKey = "HHH-12661" ) public void testUUIDBinaryTypeInParameter() { inTransaction( session -> session.createStoredProcedureQuery("test") @@ -361,4 +391,35 @@ public class StoredProcedureParameterTypeTest extends BaseNonConfigCoreFunctiona .setParameter( 1, UUID.randomUUID()) ); } + + @Test + @TestForIssue(jiraKey = "HHH-12905") + public void testStringTypeInParameterIsNull() { + inTransaction( + session -> { + ProcedureCall procedureCall = session.createStoredProcedureCall( "test" ); + procedureCall.registerParameter( 1, StringType.class, ParameterMode.IN ).enablePassingNulls( true ); + procedureCall.setParameter( 1, null ); + } + ); + } + + @Test + @TestForIssue(jiraKey = "HHH-12905") + public void testStringTypeInParameterIsNullWithoutEnablePassingNulls() { + inTransaction( + session -> { + try { + ProcedureCall procedureCall = session.createStoredProcedureCall( "test" ); + procedureCall.registerParameter( 1, StringType.class, ParameterMode.IN ); + procedureCall.setParameter( 1, null ); + + fail("Should have thrown exception"); + } + catch (IllegalArgumentException e) { + assertTrue( e.getMessage().endsWith( "You need to call ParameterRegistration#enablePassingNulls(true) in order to pass null parameters." ) ); + } + } + ); + } } \ No newline at end of file