HHH-18302 Add test for issue
This commit is contained in:
parent
8766a8e012
commit
a3c779a019
|
@ -28,10 +28,15 @@ import org.hibernate.testing.orm.junit.EntityManagerFactoryScope;
|
||||||
import org.hibernate.testing.orm.junit.Jira;
|
import org.hibernate.testing.orm.junit.Jira;
|
||||||
import org.hibernate.testing.orm.junit.Jpa;
|
import org.hibernate.testing.orm.junit.Jpa;
|
||||||
import org.hibernate.testing.orm.junit.RequiresDialect;
|
import org.hibernate.testing.orm.junit.RequiresDialect;
|
||||||
|
import org.hibernate.testing.orm.junit.SessionFactoryScope;
|
||||||
import org.junit.jupiter.api.AfterAll;
|
import org.junit.jupiter.api.AfterAll;
|
||||||
|
import org.junit.jupiter.api.AfterEach;
|
||||||
|
import org.junit.jupiter.api.Assertions;
|
||||||
import org.junit.jupiter.api.BeforeAll;
|
import org.junit.jupiter.api.BeforeAll;
|
||||||
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import jakarta.persistence.Column;
|
||||||
import jakarta.persistence.Entity;
|
import jakarta.persistence.Entity;
|
||||||
import jakarta.persistence.Id;
|
import jakarta.persistence.Id;
|
||||||
import jakarta.persistence.NamedStoredProcedureQueries;
|
import jakarta.persistence.NamedStoredProcedureQueries;
|
||||||
|
@ -39,8 +44,11 @@ import jakarta.persistence.NamedStoredProcedureQuery;
|
||||||
import jakarta.persistence.ParameterMode;
|
import jakarta.persistence.ParameterMode;
|
||||||
import jakarta.persistence.StoredProcedureParameter;
|
import jakarta.persistence.StoredProcedureParameter;
|
||||||
import jakarta.persistence.StoredProcedureQuery;
|
import jakarta.persistence.StoredProcedureQuery;
|
||||||
|
import jakarta.persistence.Table;
|
||||||
|
import org.hamcrest.MatcherAssert;
|
||||||
|
|
||||||
import static org.assertj.core.api.Assertions.assertThat;
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
import static org.hamcrest.core.Is.is;
|
||||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
import static org.junit.jupiter.api.Assertions.assertFalse;
|
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||||
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||||
|
@ -55,10 +63,16 @@ import static org.junit.jupiter.api.Assertions.fail;
|
||||||
Phone.class,
|
Phone.class,
|
||||||
Vote.class,
|
Vote.class,
|
||||||
DB2StoredProcedureTest.IdHolder.class,
|
DB2StoredProcedureTest.IdHolder.class,
|
||||||
|
DB2StoredProcedureTest.Address.class,
|
||||||
} )
|
} )
|
||||||
@RequiresDialect( value = DB2Dialect.class )
|
@RequiresDialect( value = DB2Dialect.class )
|
||||||
@Jira( "https://hibernate.atlassian.net/browse/HHH-18332" )
|
@Jira( "https://hibernate.atlassian.net/browse/HHH-18332" )
|
||||||
public class DB2StoredProcedureTest {
|
public class DB2StoredProcedureTest {
|
||||||
|
|
||||||
|
private static final String CITY = "London";
|
||||||
|
private static final String STREET = "Lollard Street";
|
||||||
|
private static final String ZIP = "SE116U";
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testStoredProcedureOutParameter(EntityManagerFactoryScope scope) {
|
public void testStoredProcedureOutParameter(EntityManagerFactoryScope scope) {
|
||||||
scope.inTransaction( entityManager -> {
|
scope.inTransaction( entityManager -> {
|
||||||
|
@ -242,6 +256,88 @@ public class DB2StoredProcedureTest {
|
||||||
} );
|
} );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@Jira( "https://hibernate.atlassian.net/browse/HHH-18302" )
|
||||||
|
public void testStoredProcedureInAndOutAndRefCursorParameters(EntityManagerFactoryScope scope) {
|
||||||
|
scope.inTransaction(
|
||||||
|
entityManager -> {
|
||||||
|
StoredProcedureQuery query = entityManager.createStoredProcedureQuery( "sp_get_address_by_street_city" );
|
||||||
|
query.registerStoredProcedureParameter( "street_in", String.class, ParameterMode.IN );
|
||||||
|
query.registerStoredProcedureParameter( "city_in", String.class, ParameterMode.IN );
|
||||||
|
query.registerStoredProcedureParameter( "rec_out", ResultSet.class, ParameterMode.REF_CURSOR );
|
||||||
|
|
||||||
|
query.setParameter( "street_in", STREET )
|
||||||
|
.setParameter( "city_in", CITY );
|
||||||
|
query.execute();
|
||||||
|
ResultSet rs = (ResultSet) query.getOutputParameterValue( "rec_out" );
|
||||||
|
try {
|
||||||
|
Assertions.assertTrue( rs.next() );
|
||||||
|
MatcherAssert.assertThat( rs.getString( "street" ), is( STREET ) );
|
||||||
|
MatcherAssert.assertThat( rs.getString( "city" ), is( CITY ) );
|
||||||
|
MatcherAssert.assertThat( rs.getString( "zip" ), is( ZIP ) );
|
||||||
|
}
|
||||||
|
catch (SQLException e) {
|
||||||
|
throw new RuntimeException( e );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@Jira( "https://hibernate.atlassian.net/browse/HHH-18302" )
|
||||||
|
public void testStoredProcedureInAndOutAndRefCursorParametersDifferentRegistrationOrder(EntityManagerFactoryScope scope) {
|
||||||
|
scope.inTransaction(
|
||||||
|
entityManager -> {
|
||||||
|
StoredProcedureQuery query = entityManager.createStoredProcedureQuery( "sp_get_address_by_street_city" );
|
||||||
|
query.registerStoredProcedureParameter( "city_in", String.class, ParameterMode.IN );
|
||||||
|
query.registerStoredProcedureParameter( "street_in", String.class, ParameterMode.IN );
|
||||||
|
query.registerStoredProcedureParameter( "rec_out", ResultSet.class, ParameterMode.REF_CURSOR );
|
||||||
|
|
||||||
|
query.setParameter( "street_in", STREET )
|
||||||
|
.setParameter( "city_in", CITY );
|
||||||
|
query.execute();
|
||||||
|
ResultSet rs = (ResultSet) query.getOutputParameterValue( "rec_out" );
|
||||||
|
try {
|
||||||
|
Assertions.assertTrue( rs.next() );
|
||||||
|
MatcherAssert.assertThat( rs.getString( "street" ), is( STREET ) );
|
||||||
|
MatcherAssert.assertThat( rs.getString( "city" ), is( CITY ) );
|
||||||
|
MatcherAssert.assertThat( rs.getString( "zip" ), is( ZIP ) );
|
||||||
|
}
|
||||||
|
catch (SQLException e) {
|
||||||
|
throw new RuntimeException( e );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@Jira( "https://hibernate.atlassian.net/browse/HHH-18302" )
|
||||||
|
public void testStoredProcedureInAndOutAndRefCursorParametersDifferentRegistrationOrder2(EntityManagerFactoryScope scope) {
|
||||||
|
scope.inTransaction(
|
||||||
|
entityManager -> {
|
||||||
|
StoredProcedureQuery query = entityManager.createStoredProcedureQuery( "sp_get_address_by_street_city" );
|
||||||
|
query.registerStoredProcedureParameter( "rec_out", ResultSet.class, ParameterMode.REF_CURSOR );
|
||||||
|
query.registerStoredProcedureParameter( "city_in", String.class, ParameterMode.IN );
|
||||||
|
query.registerStoredProcedureParameter( "street_in", String.class, ParameterMode.IN );
|
||||||
|
|
||||||
|
query.setParameter( "street_in", STREET )
|
||||||
|
.setParameter( "city_in", CITY );
|
||||||
|
query.execute();
|
||||||
|
ResultSet rs = (ResultSet) query.getOutputParameterValue( "rec_out" );
|
||||||
|
try {
|
||||||
|
Assertions.assertTrue( rs.next() );
|
||||||
|
MatcherAssert.assertThat( rs.getString( "street" ), is( STREET ) );
|
||||||
|
MatcherAssert.assertThat( rs.getString( "city" ), is( CITY ) );
|
||||||
|
MatcherAssert.assertThat( rs.getString( "zip" ), is( ZIP ) );
|
||||||
|
}
|
||||||
|
catch (SQLException e) {
|
||||||
|
throw new RuntimeException( e );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@BeforeAll
|
@BeforeAll
|
||||||
public void prepareSchema(EntityManagerFactoryScope scope) {
|
public void prepareSchema(EntityManagerFactoryScope scope) {
|
||||||
scope.inTransaction( (entityManager) -> entityManager.unwrap( Session.class ).doWork( (connection) -> {
|
scope.inTransaction( (entityManager) -> entityManager.unwrap( Session.class ).doWork( (connection) -> {
|
||||||
|
@ -355,9 +451,27 @@ public class DB2StoredProcedureTest {
|
||||||
" OPEN votes; " +
|
" OPEN votes; " +
|
||||||
"END"
|
"END"
|
||||||
);
|
);
|
||||||
|
statement.executeUpdate(
|
||||||
|
"CREATE OR REPLACE PROCEDURE sp_get_address_by_street_city ( " +
|
||||||
|
" IN street_in VARCHAR(255), " +
|
||||||
|
" IN city_in VARCHAR(255), " +
|
||||||
|
" OUT rec_out CURSOR ) " +
|
||||||
|
"BEGIN " +
|
||||||
|
" SET rec_out = CURSOR FOR " +
|
||||||
|
" SELECT * " +
|
||||||
|
" FROM ADDRESS_TABLE A " +
|
||||||
|
" WHERE " +
|
||||||
|
" A.STREET = street_in" +
|
||||||
|
" AND A.CITY = city_in;" +
|
||||||
|
" OPEN rec_out; " +
|
||||||
|
"END;"
|
||||||
|
);
|
||||||
}
|
}
|
||||||
} ) );
|
} ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
@BeforeEach
|
||||||
|
public void setUp(EntityManagerFactoryScope scope){
|
||||||
scope.inTransaction( (entityManager) -> {
|
scope.inTransaction( (entityManager) -> {
|
||||||
final Person person1 = new Person( 1L, "John Doe" );
|
final Person person1 = new Person( 1L, "John Doe" );
|
||||||
person1.setNickName( "JD" );
|
person1.setNickName( "JD" );
|
||||||
|
@ -377,6 +491,8 @@ public class DB2StoredProcedureTest {
|
||||||
phone2.setValid( false );
|
phone2.setValid( false );
|
||||||
|
|
||||||
person1.addPhone( phone2 );
|
person1.addPhone( phone2 );
|
||||||
|
Address address = new Address( 1l, STREET, CITY, ZIP );
|
||||||
|
entityManager.persist( address );
|
||||||
} );
|
} );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -394,15 +510,21 @@ public class DB2StoredProcedureTest {
|
||||||
statement.executeUpdate( "DROP PROCEDURE outAndRefCursor" );
|
statement.executeUpdate( "DROP PROCEDURE outAndRefCursor" );
|
||||||
statement.executeUpdate( "DROP PROCEDURE sp_phone_validity" );
|
statement.executeUpdate( "DROP PROCEDURE sp_phone_validity" );
|
||||||
statement.executeUpdate( "DROP PROCEDURE sp_votes" );
|
statement.executeUpdate( "DROP PROCEDURE sp_votes" );
|
||||||
|
statement.executeUpdate( "DROP PROCEDURE sp_get_address_by_street_city" );
|
||||||
}
|
}
|
||||||
catch (final SQLException ignore) {
|
catch (final SQLException ignore) {
|
||||||
}
|
}
|
||||||
} );
|
} );
|
||||||
|
} );
|
||||||
|
}
|
||||||
|
|
||||||
scope.inTransaction( em, (em2) -> {
|
@AfterEach
|
||||||
final List<Person> people = em.createQuery( "from Person", Person.class ).getResultList();
|
public void cleanData(EntityManagerFactoryScope scope) {
|
||||||
people.forEach( em::remove );
|
scope.inTransaction( (em) -> {
|
||||||
} );
|
final List<Person> people = em.createQuery( "from Person", Person.class ).getResultList();
|
||||||
|
people.forEach( em::remove );
|
||||||
|
|
||||||
|
em.createQuery( "delete Address" ).executeUpdate();
|
||||||
} );
|
} );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -429,4 +551,44 @@ public class DB2StoredProcedureTest {
|
||||||
Long id;
|
Long id;
|
||||||
String name;
|
String name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Entity(name = "Address")
|
||||||
|
@Table(name = "ADDRESS_TABLE")
|
||||||
|
public static class Address {
|
||||||
|
@Id
|
||||||
|
@Column(name = "ID")
|
||||||
|
private long id;
|
||||||
|
@Column(name = "STREET")
|
||||||
|
private String street;
|
||||||
|
@Column(name = "CITY")
|
||||||
|
private String city;
|
||||||
|
@Column(name = "ZIP")
|
||||||
|
private String zip;
|
||||||
|
|
||||||
|
public Address() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public Address(long id, String street, String city, String zip) {
|
||||||
|
this.id = id;
|
||||||
|
this.street = street;
|
||||||
|
this.city = city;
|
||||||
|
this.zip = zip;
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getStreet() {
|
||||||
|
return street;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getCity() {
|
||||||
|
return city;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getZip() {
|
||||||
|
return zip;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -186,7 +186,7 @@
|
||||||
<sql-query name="simpleScalar" callable="true">
|
<sql-query name="simpleScalar" callable="true">
|
||||||
<return-scalar column="name" type="string"/>
|
<return-scalar column="name" type="string"/>
|
||||||
<return-scalar column="`value`" type="long"/>
|
<return-scalar column="`value`" type="long"/>
|
||||||
{ call simpleScalar(:number) }
|
{ call simpleScalar(:p_number) }
|
||||||
</sql-query>
|
</sql-query>
|
||||||
|
|
||||||
<sql-query name="paramhandling" callable="true">
|
<sql-query name="paramhandling" callable="true">
|
||||||
|
@ -261,10 +261,10 @@
|
||||||
|
|
||||||
<database-object>
|
<database-object>
|
||||||
<create>
|
<create>
|
||||||
CREATE PROCEDURE simpleScalar (IN j SMALLINT) RESULT SETS 1
|
CREATE PROCEDURE simpleScalar (IN p_number SMALLINT) RESULT SETS 1
|
||||||
P1: BEGIN
|
P1: BEGIN
|
||||||
DECLARE C1 CURSOR WITH RETURN FOR
|
DECLARE C1 CURSOR WITH RETURN FOR
|
||||||
SELECT j as value, 'getAll' as name from sysibm.sysdummy1;
|
SELECT p_number as value, 'getAll' as name from sysibm.sysdummy1;
|
||||||
OPEN C1;
|
OPEN C1;
|
||||||
END P1
|
END P1
|
||||||
</create>
|
</create>
|
||||||
|
|
Loading…
Reference in New Issue