From a5f20d23ce3cdc3a8f348d7abea9ec98f4bd508f Mon Sep 17 00:00:00 2001 From: Thomas Darimont Date: Fri, 16 Jan 2015 10:01:31 +0100 Subject: [PATCH] DATAJPA-652 - Added support for REF_CURSOR output parameters for stored procedures. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We now support detecting output parameters for stored-procedures with ParameterMode.REF_CURSOR. Previously we only considered parameters with OUT or INOUT mode as output parameters. Added additional test cases for various procedure definition options. Introduced new Dummy test type to avoid polluting the User test type anymore with additional procedure definitions. Added test for eclipse link and Openjpa but I had to deactivate them since they currently need to be run with HSQLDB V1 which doesn’t support stored procedures. Original pull request: #130. --- .../query/StoredProcedureAttributeSource.java | 62 +++-- .../data/jpa/domain/sample/Dummy.java | 116 ++++++++++ .../data/jpa/domain/sample/User.java | 6 +- ...seLinkStoredProcedureIntegrationTests.java | 28 +++ ...penJpaStoredProcedureIntegrationTests.java | 31 +++ .../StoredProcedureIntegrationTests.java | 214 ++++++++++++++++++ .../repository/sample/DummyRepository.java | 63 ++++++ .../jpa/support/EntityManagerTestUtils.java | 6 +- src/test/resources/META-INF/persistence.xml | 5 + src/test/resources/META-INF/persistence2.xml | 4 +- .../scripts/schema-stored-procedures.sql | 69 +++++- 11 files changed, 577 insertions(+), 27 deletions(-) create mode 100644 src/test/java/org/springframework/data/jpa/domain/sample/Dummy.java create mode 100644 src/test/java/org/springframework/data/jpa/repository/EclipseLinkStoredProcedureIntegrationTests.java create mode 100644 src/test/java/org/springframework/data/jpa/repository/OpenJpaStoredProcedureIntegrationTests.java create mode 100644 src/test/java/org/springframework/data/jpa/repository/StoredProcedureIntegrationTests.java create mode 100644 src/test/java/org/springframework/data/jpa/repository/sample/DummyRepository.java diff --git a/src/main/java/org/springframework/data/jpa/repository/query/StoredProcedureAttributeSource.java b/src/main/java/org/springframework/data/jpa/repository/query/StoredProcedureAttributeSource.java index 98035fd03..47fef757c 100644 --- a/src/main/java/org/springframework/data/jpa/repository/query/StoredProcedureAttributeSource.java +++ b/src/main/java/org/springframework/data/jpa/repository/query/StoredProcedureAttributeSource.java @@ -1,5 +1,5 @@ /* - * Copyright 2014 the original author or authors. + * Copyright 2014-2015 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -57,7 +57,7 @@ enum StoredProcedureAttributeSource { procedure); if (namedStoredProc != null) { - return newProcedureAttributesFrom(method, namedStoredProc); + return newProcedureAttributesFrom(method, namedStoredProc, procedure); } String procedureName = deriveProcedureNameFrom(method, procedure); @@ -90,31 +90,55 @@ enum StoredProcedureAttributeSource { /** * @param method * @param namedStoredProc + * @param procedure * @return */ - private StoredProcedureAttributes newProcedureAttributesFrom(Method method, NamedStoredProcedureQuery namedStoredProc) { + private StoredProcedureAttributes newProcedureAttributesFrom(Method method, + NamedStoredProcedureQuery namedStoredProc, Procedure procedure) { String outputParameterName = null; Class outputParameterType = null; - int outputParameterCount = 0; + if (!procedure.outputParameterName().isEmpty()) { + + // we give the output parameter definition from the @Procedure annotation precedence + outputParameterName = procedure.outputParameterName(); + } else { + + // try to discover the output parameter + List outputParameters = extractOutputParametersFrom(namedStoredProc); + + if (outputParameters.size() != 1 && !void.class.equals(method.getReturnType())) { + throw new IllegalStateException(String.format( + "Could not create ProcedureAttributes from %s. We currently support exactly one output parameter!", method)); + } + + if (!outputParameters.isEmpty()) { + StoredProcedureParameter outputParameter = outputParameters.get(0); + outputParameterName = outputParameter.name(); + outputParameterType = outputParameter.type(); + } + } + + if (outputParameterType == null || Object.class.equals(outputParameterType) + || void.class.equals(outputParameterType)) { + outputParameterType = method.getReturnType(); + } + + return new StoredProcedureAttributes(namedStoredProc.name(), outputParameterName, outputParameterType, true); + } + + private List extractOutputParametersFrom(NamedStoredProcedureQuery namedStoredProc) { + + List outputParameters = new ArrayList(); for (StoredProcedureParameter param : namedStoredProc.parameters()) { + switch (param.mode()) { case OUT: case INOUT: - - if (outputParameterCount > 0) { - throw new IllegalStateException( - String.format( - "Could not create ProcedureAttributes from %s. We currently support only one output parameter!", - method)); - } - - outputParameterName = param.name(); - outputParameterType = param.type(); - - outputParameterCount++; + case REF_CURSOR: + outputParameters.add(param); break; case IN: default: @@ -122,11 +146,7 @@ enum StoredProcedureAttributeSource { } } - if (outputParameterType == null) { - outputParameterType = method.getReturnType(); - } - - return new StoredProcedureAttributes(namedStoredProc.name(), outputParameterName, outputParameterType, true); + return outputParameters; } /** diff --git a/src/test/java/org/springframework/data/jpa/domain/sample/Dummy.java b/src/test/java/org/springframework/data/jpa/domain/sample/Dummy.java new file mode 100644 index 000000000..ead55531d --- /dev/null +++ b/src/test/java/org/springframework/data/jpa/domain/sample/Dummy.java @@ -0,0 +1,116 @@ +/* + * Copyright 2015 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.data.jpa.domain.sample; + +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.Id; +import javax.persistence.NamedStoredProcedureQueries; +import javax.persistence.NamedStoredProcedureQuery; +import javax.persistence.ParameterMode; +import javax.persistence.StoredProcedureParameter; + +import org.springframework.util.ObjectUtils; + +/** + * Sample domain class representing used for Stored Procedure tests. + * + * @author Thomas Darimont + */ +@Entity +@NamedStoredProcedureQueries({ // + @NamedStoredProcedureQuery(name = "Dummy.procedureWith1InputAnd1OutputParameter", + procedureName = "procedure_in1_out1", parameters = { + @StoredProcedureParameter(mode = ParameterMode.IN, type = Integer.class), + @StoredProcedureParameter(mode = ParameterMode.OUT, type = Integer.class) }) // + , + @NamedStoredProcedureQuery(name = "Dummy.procedureWith1InputAndNoOutputParameter", + procedureName = "procedure_in1_out0", parameters = { @StoredProcedureParameter(mode = ParameterMode.IN, + type = Integer.class) }) // + , + @NamedStoredProcedureQuery(name = "Dummy.procedureWithNoInputAnd1OutputParameter", + procedureName = "procedure_in0_out1", parameters = { @StoredProcedureParameter(mode = ParameterMode.OUT, + type = Integer.class) }) // + , + @NamedStoredProcedureQuery(name = "Dummy.procedureWith1InputAnd1OutputParameterWithResultSet", + procedureName = "procedure_in1_out0_return_rs_no_update", parameters = { + @StoredProcedureParameter(mode = ParameterMode.IN, type = Integer.class), + @StoredProcedureParameter(mode = ParameterMode.REF_CURSOR, type = void.class) }) // + , + @NamedStoredProcedureQuery(name = "Dummy.procedureWith1InputAnd1OutputParameterWithResultSetWithUpdate", + procedureName = "procedure_in1_out0_return_rs_with_update", parameters = { + @StoredProcedureParameter(mode = ParameterMode.IN, type = Integer.class), + @StoredProcedureParameter(mode = ParameterMode.REF_CURSOR, type = void.class) }) // + , + @NamedStoredProcedureQuery(name = "Dummy.procedureWith1InputAndNoOutputParameterWithUpdate", + procedureName = "procedure_in1_out0_no_return_with_update", parameters = { @StoredProcedureParameter( + mode = ParameterMode.IN, type = String.class) }) // +}) +public class Dummy { + + @Id @GeneratedValue private Integer id; + private String name; + + public Dummy() {} + + public Dummy(String name) { + this.name = name; + } + + public Integer getId() { + return id; + } + + public void setId(Integer id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + @Override + public String toString() { + return "Dummy [id=" + id + ", name=" + name + "]"; + } + + @Override + public int hashCode() { + return ObjectUtils.nullSafeHashCode(name); + } + + @Override + public boolean equals(Object that) { + + if (that == this) { + return true; + } + + if (that == null) { + return false; + } + + if (!(that instanceof Dummy)) { + return false; + } + + return ObjectUtils.nullSafeEquals(this.name, ((Dummy) that).name); + } +} diff --git a/src/test/java/org/springframework/data/jpa/domain/sample/User.java b/src/test/java/org/springframework/data/jpa/domain/sample/User.java index 94c7e213c..3ca89ed80 100644 --- a/src/test/java/org/springframework/data/jpa/domain/sample/User.java +++ b/src/test/java/org/springframework/data/jpa/domain/sample/User.java @@ -1,5 +1,5 @@ /* - * Copyright 2008-2014 the original author or authors. + * Copyright 2008-2015 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -84,7 +84,7 @@ public class User { @Lob private byte[] binaryData; @ElementCollection private Set attributes; - + @Temporal(TemporalType.DATE) private Date dateOfBirth; /** @@ -367,7 +367,7 @@ public class User { public void setAttributes(Set attributes) { this.attributes = attributes; } - + public Date getDateOfBirth() { return dateOfBirth; } diff --git a/src/test/java/org/springframework/data/jpa/repository/EclipseLinkStoredProcedureIntegrationTests.java b/src/test/java/org/springframework/data/jpa/repository/EclipseLinkStoredProcedureIntegrationTests.java new file mode 100644 index 000000000..4219e9d54 --- /dev/null +++ b/src/test/java/org/springframework/data/jpa/repository/EclipseLinkStoredProcedureIntegrationTests.java @@ -0,0 +1,28 @@ +/* + * Copyright 2008-2015 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.data.jpa.repository; + +import org.springframework.context.annotation.ImportResource; +import org.springframework.test.context.ContextConfiguration; + +/** + * Testcase to run {@link StoredProcedureIntegrationTests} integration tests on top of EclipseLink. + * + * @author Thomas Darimont + */ +@ContextConfiguration(classes = { StoredProcedureIntegrationTests.Config.class }) +@ImportResource("classpath:eclipselink.xml") +public class EclipseLinkStoredProcedureIntegrationTests extends StoredProcedureIntegrationTests {} diff --git a/src/test/java/org/springframework/data/jpa/repository/OpenJpaStoredProcedureIntegrationTests.java b/src/test/java/org/springframework/data/jpa/repository/OpenJpaStoredProcedureIntegrationTests.java new file mode 100644 index 000000000..00c24ccf1 --- /dev/null +++ b/src/test/java/org/springframework/data/jpa/repository/OpenJpaStoredProcedureIntegrationTests.java @@ -0,0 +1,31 @@ +/* + * Copyright 2015 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.data.jpa.repository; + +import org.junit.Ignore; +import org.springframework.context.annotation.ImportResource; +import org.springframework.test.context.ContextConfiguration; + +/** + * Test case to run {@link StoredProcedureIntegrationTests} integration tests on top of OpenJpa. This is currently not + * supported since, the OpenJPA tests need to be executed with hsqldb1 which doesn't supported stored procedures. + * + * @author Thomas Darimont + */ +@Ignore +@ContextConfiguration(classes = { StoredProcedureIntegrationTests.Config.class }) +@ImportResource("classpath:openjpa.xml") +public class OpenJpaStoredProcedureIntegrationTests extends StoredProcedureIntegrationTests {} diff --git a/src/test/java/org/springframework/data/jpa/repository/StoredProcedureIntegrationTests.java b/src/test/java/org/springframework/data/jpa/repository/StoredProcedureIntegrationTests.java new file mode 100644 index 000000000..cce06e9ba --- /dev/null +++ b/src/test/java/org/springframework/data/jpa/repository/StoredProcedureIntegrationTests.java @@ -0,0 +1,214 @@ +/* + * Copyright 2015 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.data.jpa.repository; + +import static org.hamcrest.CoreMatchers.*; +import static org.junit.Assert.*; +import static org.junit.Assume.*; +import static org.springframework.data.jpa.support.EntityManagerTestUtils.*; + +import java.util.List; + +import javax.persistence.EntityManager; +import javax.persistence.PersistenceContext; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.ComponentScan.Filter; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.FilterType; +import org.springframework.context.annotation.ImportResource; +import org.springframework.data.jpa.domain.sample.Dummy; +import org.springframework.data.jpa.repository.config.EnableJpaRepositories; +import org.springframework.data.jpa.repository.sample.DummyRepository; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import org.springframework.transaction.annotation.Transactional; + +/** + * @see scripts/schema-stored-procedures.sql for procedure definitions. + * @author Thomas Darimont + */ +@Transactional +@ContextConfiguration +@RunWith(SpringJUnit4ClassRunner.class) +public class StoredProcedureIntegrationTests { + + @PersistenceContext EntityManager em; + @Autowired DummyRepository repository; + + Dummy dummyA; + Dummy dummyB; + Dummy dummyC; + + @Configuration + @EnableJpaRepositories(basePackageClasses = DummyRepository.class, includeFilters = { @Filter( + pattern = ".*DummyRepository", type = FilterType.REGEX) }) + @ImportResource("classpath:infrastructure.xml") + static class Config {} + + @Before + public void setup() { + + assumeTrue(currentEntityManagerIsAJpa21EntityManager(em)); + + dummyA = em.merge(new Dummy("A")); + dummyB = em.merge(new Dummy("B")); + dummyC = em.merge(new Dummy("C")); + } + + /** + * @see DATAJPA-652 + */ + @Test + public void shouldExecuteAdHocProcedureWithNoInputAnd1OutputParameter() { + assertThat(repository.adHocProcedureWithNoInputAnd1OutputParameter(), is(equalTo(42))); + } + + /** + * @see DATAJPA-652 + */ + @Test + public void shouldExecuteAdHocProcedureWith1InputAnd1OutputParameter() { + assertThat(repository.adHocProcedureWith1InputAnd1OutputParameter(23), is(equalTo(24))); + } + + /** + * @see DATAJPA-652 + */ + @Test + public void shouldExecuteAdHocProcedureWith1InputAndNoOutputParameter() { + + repository.adHocProcedureWith1InputAndNoOutputParameter(42); + + assertTrue(true); + } + + /** + * @see DATAJPA-652 + */ + @Test + public void shouldExecuteAdHocProcedureWith1InputAnd1OutputParameterWithResultSet() { + + // hibernate currently (v4.3) doesn't support returning ResultSets in output parameters + assumeFalse(currentEntityManagerIsHibernateEntityManager(em)); + + List dummies = repository.adHocProcedureWith1InputAnd1OutputParameterWithResultSet("FOO"); + + System.out.println("### Found dummies: " + dummies); + + assertThat(dummies, is(notNullValue())); + assertThat(dummies.size(), is(equalTo(3))); + } + + /** + * @see DATAJPA-652 + */ + @Test + public void shouldExecuteAdHocProcedureWith1InputAnd1OutputParameterWithResultSetWithUpdate() { + + // hibernate currently (v4.3) doesn't support returning ResultSets in output parameters + assumeFalse(currentEntityManagerIsHibernateEntityManager(em)); + + List dummies = repository.adHocProcedureWith1InputAnd1OutputParameterWithResultSetWithUpdate("FOO"); + + System.out.println("### Found dummies: " + dummies); + + assertThat(dummies, is(notNullValue())); + assertThat(dummies.size(), is(equalTo(3))); + } + + /** + * @see DATAJPA-652 + */ + @Test + public void shouldExecuteAdHocProcedureWith1InputAnd1OutputParameterWithUpdate() { + + repository.adHocProcedureWith1InputAndNoOutputParameterWithUpdate("FOO"); + + assertTrue(true); + } + + /** + * @see DATAJPA-652 + */ + @Test + public void shouldExecuteProcedureWithNoInputAnd1OutputParameter() { + assertThat(repository.procedureWithNoInputAnd1OutputParameter(), is(equalTo(42))); + } + + /** + * @see DATAJPA-652 + */ + @Test + public void shouldExecuteProcedureWith1InputAnd1OutputParameter() { + assertThat(repository.procedureWith1InputAnd1OutputParameter(23), is(equalTo(24))); + } + + /** + * @see DATAJPA-652 + */ + @Test + public void shouldExecuteProcedureWith1InputAndNoOutputParameter() { + + repository.procedureWith1InputAndNoOutputParameter(42); + + assertTrue(true); + } + + /** + * @see DATAJPA-652 + */ + @Test + public void shouldExecuteProcedureWith1InputAnd1OutputParameterWithResultSet() { + + // hibernate currently (v4.3) doesn't support returning ResultSets in output parameters + assumeFalse(currentEntityManagerIsHibernateEntityManager(em)); + + List dummies = repository.procedureWith1InputAnd1OutputParameterWithResultSet("FOO"); + + assertThat(dummies, is(notNullValue())); + assertThat(dummies.size(), is(equalTo(3))); + } + + /** + * @see DATAJPA-652 + */ + @Test + public void shouldExecuteProcedureWith1InputAnd1OutputParameterWithResultSetWithUpdate() { + + // hibernate currently (v4.3) doesn't support returning ResultSets in output parameters + assumeFalse(currentEntityManagerIsHibernateEntityManager(em)); + + List dummies = repository.procedureWith1InputAnd1OutputParameterWithResultSetWithUpdate("FOO"); + + assertThat(dummies, is(notNullValue())); + assertThat(dummies.size(), is(equalTo(3))); + } + + /** + * @see DATAJPA-652 + */ + @Test + public void shouldExecuteProcedureWith1InputAnd1OutputParameterWithUpdate() { + + repository.procedureWith1InputAndNoOutputParameterWithUpdate("FOO"); + + assertTrue(true); + } +} diff --git a/src/test/java/org/springframework/data/jpa/repository/sample/DummyRepository.java b/src/test/java/org/springframework/data/jpa/repository/sample/DummyRepository.java new file mode 100644 index 000000000..67c98399c --- /dev/null +++ b/src/test/java/org/springframework/data/jpa/repository/sample/DummyRepository.java @@ -0,0 +1,63 @@ +/* + * Copyright 2015 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.data.jpa.repository.sample; + +import java.util.List; + +import org.springframework.data.jpa.domain.sample.Dummy; +import org.springframework.data.jpa.repository.query.Procedure; +import org.springframework.data.repository.CrudRepository; +import org.springframework.transaction.annotation.Transactional; + +@Transactional +public interface DummyRepository extends CrudRepository { + + @Procedure("procedure_in1_out1") + Integer adHocProcedureWith1InputAnd1OutputParameter(Integer in); + + @Procedure("procedure_in1_out0") + void adHocProcedureWith1InputAndNoOutputParameter(Integer in); + + @Procedure("procedure_in0_out1") + Integer adHocProcedureWithNoInputAnd1OutputParameter(); + + @Procedure("procedure_in1_out0_return_rs_no_update") + List adHocProcedureWith1InputAnd1OutputParameterWithResultSet(String in); + + @Procedure("procedure_in1_out0_return_rs_with_update") + List adHocProcedureWith1InputAnd1OutputParameterWithResultSetWithUpdate(String in); + + @Procedure("procedure_in1_out0_no_return_with_update") + void adHocProcedureWith1InputAndNoOutputParameterWithUpdate(String in); + + @Procedure + Integer procedureWith1InputAnd1OutputParameter(Integer in); + + @Procedure + void procedureWith1InputAndNoOutputParameter(Integer in); + + @Procedure + Integer procedureWithNoInputAnd1OutputParameter(); + + @Procedure + List procedureWith1InputAnd1OutputParameterWithResultSet(String in); + + @Procedure + List procedureWith1InputAnd1OutputParameterWithResultSetWithUpdate(String in); + + @Procedure + void procedureWith1InputAndNoOutputParameterWithUpdate(String in); +} diff --git a/src/test/java/org/springframework/data/jpa/support/EntityManagerTestUtils.java b/src/test/java/org/springframework/data/jpa/support/EntityManagerTestUtils.java index f1797888f..c9494d573 100644 --- a/src/test/java/org/springframework/data/jpa/support/EntityManagerTestUtils.java +++ b/src/test/java/org/springframework/data/jpa/support/EntityManagerTestUtils.java @@ -1,5 +1,5 @@ /* - * Copyright 2014 the original author or authors. + * Copyright 2014-2015 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -32,4 +32,8 @@ public abstract class EntityManagerTestUtils { return ReflectionUtils.findMethod(((org.springframework.orm.jpa.EntityManagerProxy) em).getTargetEntityManager() .getClass(), "getEntityGraph", String.class) != null; } + + public static boolean currentEntityManagerIsHibernateEntityManager(EntityManager em) { + return em.getDelegate().getClass().getName().toLowerCase().contains("hibernate"); + } } diff --git a/src/test/resources/META-INF/persistence.xml b/src/test/resources/META-INF/persistence.xml index eac990698..82189b1b0 100644 --- a/src/test/resources/META-INF/persistence.xml +++ b/src/test/resources/META-INF/persistence.xml @@ -38,6 +38,7 @@ org.springframework.data.jpa.domain.sample.SpecialUser org.springframework.data.jpa.domain.sample.User org.springframework.data.jpa.domain.sample.VersionedUser + org.springframework.data.jpa.domain.sample.Dummy true @@ -46,6 +47,7 @@ org.springframework.data.jpa.domain.sample.MailSender org.springframework.data.jpa.domain.sample.MailUser org.springframework.data.jpa.domain.sample.User + org.springframework.data.jpa.domain.sample.Dummy true @@ -55,6 +57,7 @@ org.springframework.data.jpa.domain.sample.MailUser org.springframework.data.jpa.domain.sample.User org.springframework.data.jpa.repository.cdi.Person + org.springframework.data.jpa.domain.sample.Dummy true @@ -101,6 +104,7 @@ org.springframework.data.jpa.domain.sample.MailUser org.springframework.data.jpa.domain.sample.User org.springframework.data.jpa.repository.support.JpaMetamodelEntityInformationIntegrationTests$Sample + org.springframework.data.jpa.domain.sample.Dummy true @@ -111,6 +115,7 @@ org.springframework.data.jpa.domain.sample.MailUser org.springframework.data.jpa.domain.sample.User org.springframework.data.jpa.repository.support.JpaMetamodelEntityInformationIntegrationTests$Sample + org.springframework.data.jpa.domain.sample.Dummy true diff --git a/src/test/resources/META-INF/persistence2.xml b/src/test/resources/META-INF/persistence2.xml index f0d7af10a..18c3c67b1 100644 --- a/src/test/resources/META-INF/persistence2.xml +++ b/src/test/resources/META-INF/persistence2.xml @@ -15,6 +15,7 @@ org.springframework.data.jpa.domain.sample.Role org.springframework.data.jpa.domain.sample.SpecialUser org.springframework.data.jpa.domain.sample.User + org.springframework.data.jpa.domain.sample.Dummy true @@ -22,7 +23,7 @@ org.springframework.data.jpa.domain.sample.AuditableUser org.springframework.data.jpa.domain.sample.AuditableRole org.springframework.data.jpa.domain.sample.Category -org.springframework.data.jpa.domain.sample.CustomAbstractPersistable + org.springframework.data.jpa.domain.sample.CustomAbstractPersistable org.springframework.data.jpa.domain.sample.MailMessage org.springframework.data.jpa.domain.sample.MailSender org.springframework.data.jpa.domain.sample.MailUser @@ -30,6 +31,7 @@ org.springframework.data.jpa.domain.sample.Role org.springframework.data.jpa.domain.sample.SpecialUser org.springframework.data.jpa.domain.sample.User + org.springframework.data.jpa.domain.sample.Dummy true diff --git a/src/test/resources/scripts/schema-stored-procedures.sql b/src/test/resources/scripts/schema-stored-procedures.sql index dee6b566c..f2df7ff73 100644 --- a/src/test/resources/scripts/schema-stored-procedures.sql +++ b/src/test/resources/scripts/schema-stored-procedures.sql @@ -5,4 +5,71 @@ CREATE procedure plus1inout (IN arg int, OUT res int) BEGIN ATOMIC set res = arg + 1; END -/; \ No newline at end of file +/; +DROP procedure IF EXISTS procedure_in1_out1 +/; +DROP procedure IF EXISTS procedure_in1_out0 +/; +DROP procedure IF EXISTS procedure_in0_out1 +/; +DROP procedure IF EXISTS procedure_in1_out0_return_rs_no_update +/; +DROP procedure IF EXISTS procedure_in1_out0_return_rs_with_update +/; +DROP procedure IF EXISTS procedure_in1_out0_no_return_with_update +/; + +DROP table dummy if exists +/; +create table dummy (id int GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, name VARCHAR(32)) +/; +insert into public.dummy(name) values ('A') +/; +insert into public.dummy(name) values ('B') +/; +insert into public.dummy(name) values ('C') +/; + +/; +CREATE procedure procedure_in1_out1 (IN arg int, OUT res int) +BEGIN ATOMIC +set res = arg + 1; +END +/; + +CREATE procedure procedure_in1_out0 (IN arg int) +BEGIN ATOMIC +DECLARE res int; +set res = arg + 1; +END +/; + +CREATE procedure procedure_in0_out1 (OUT res int) +BEGIN ATOMIC +set res = 42; +END +/; + +CREATE procedure procedure_in1_out0_return_rs_no_update (IN arg varchar(32)) +READS SQL DATA DYNAMIC RESULT SETS 1 +BEGIN ATOMIC +DECLARE result CURSOR WITH RETURN FOR SELECT * FROM public.dummy FOR READ ONLY; +open result; +END +/; + +CREATE procedure procedure_in1_out0_return_rs_with_update (IN arg varchar(32)) +MODIFIES SQL DATA DYNAMIC RESULT SETS 1 +BEGIN ATOMIC +DECLARE result CURSOR WITH RETURN FOR SELECT * FROM public.dummy FOR READ ONLY; +update public.dummy set name = name; +OPEN result; +END +/; + +CREATE procedure procedure_in1_out0_no_return_with_update (IN arg varchar(32)) +MODIFIES SQL DATA +BEGIN ATOMIC +update public.dummy set name = name; +END +/;