diff --git a/spring-data-jpa/src/test/java/org/springframework/data/jpa/repository/procedures/MySqlStoredProcedureIntegrationTests.java b/spring-data-jpa/src/test/java/org/springframework/data/jpa/repository/procedures/MySqlStoredProcedureIntegrationTests.java index ec37517f2..b248e809f 100644 --- a/spring-data-jpa/src/test/java/org/springframework/data/jpa/repository/procedures/MySqlStoredProcedureIntegrationTests.java +++ b/spring-data-jpa/src/test/java/org/springframework/data/jpa/repository/procedures/MySqlStoredProcedureIntegrationTests.java @@ -19,20 +19,17 @@ package org.springframework.data.jpa.repository.procedures; import static org.assertj.core.api.Assertions.*; import jakarta.persistence.Entity; -import jakarta.persistence.EntityManagerFactory; import jakarta.persistence.GeneratedValue; import jakarta.persistence.Id; import jakarta.persistence.NamedStoredProcedureQuery; import java.util.List; import java.util.Objects; -import java.util.Properties; - -import javax.sql.DataSource; import org.hibernate.dialect.MySQLDialect; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; + import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan.Filter; @@ -41,20 +38,12 @@ import org.springframework.core.io.ClassPathResource; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.config.EnableJpaRepositories; import org.springframework.data.jpa.repository.query.Procedure; -import org.springframework.jdbc.datasource.init.DataSourceInitializer; -import org.springframework.jdbc.datasource.init.ResourceDatabasePopulator; -import org.springframework.orm.jpa.AbstractEntityManagerFactoryBean; -import org.springframework.orm.jpa.JpaTransactionManager; -import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean; -import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit.jupiter.SpringExtension; -import org.springframework.transaction.PlatformTransactionManager; import org.springframework.transaction.annotation.EnableTransactionManagement; import org.springframework.transaction.annotation.Transactional; -import org.testcontainers.containers.MySQLContainer; -import com.mysql.cj.jdbc.MysqlDataSource; +import org.testcontainers.containers.MySQLContainer; /** * Testcase to verify {@link org.springframework.jdbc.object.StoredProcedure}s work with MySQL. @@ -234,7 +223,11 @@ class MySqlStoredProcedureIntegrationTests { basePackageClasses = Config.class, // includeFilters = @Filter(type = FilterType.ASSIGNABLE_TYPE, classes = EmployeeRepositoryWithNoCursor.class)) @EnableTransactionManagement - static class Config { + static class Config extends StoredProcedureConfigSupport { + + public Config() { + super(MySQLDialect.class, new ClassPathResource("scripts/mysql-stored-procedures.sql")); + } @SuppressWarnings("resource") @Bean(initMethod = "start", destroyMethod = "stop") @@ -245,51 +238,5 @@ class MySqlStoredProcedureIntegrationTests { .withPassword("test") // .withConfigurationOverride(""); } - - @Bean - public DataSource dataSource(MySQLContainer container) { - - MysqlDataSource dataSource = new MysqlDataSource(); - dataSource.setUrl(container.getJdbcUrl()); - dataSource.setUser(container.getUsername()); - dataSource.setPassword(container.getPassword()); - return dataSource; - } - - @Bean - public AbstractEntityManagerFactoryBean entityManagerFactory(DataSource dataSource) { - - LocalContainerEntityManagerFactoryBean factoryBean = new LocalContainerEntityManagerFactoryBean(); - factoryBean.setDataSource(dataSource); - factoryBean.setPersistenceUnitRootLocation("simple-persistence"); - factoryBean.setJpaVendorAdapter(new HibernateJpaVendorAdapter()); - factoryBean.setPackagesToScan(this.getClass().getPackage().getName()); - - Properties properties = new Properties(); - properties.setProperty("hibernate.hbm2ddl.auto", "create"); - properties.setProperty("hibernate.dialect", MySQLDialect.class.getCanonicalName()); - factoryBean.setJpaProperties(properties); - - return factoryBean; - } - - @Bean - PlatformTransactionManager transactionManager(EntityManagerFactory entityManagerFactory) { - return new JpaTransactionManager(entityManagerFactory); - } - - @Bean - DataSourceInitializer initializer(DataSource dataSource) { - - DataSourceInitializer initializer = new DataSourceInitializer(); - initializer.setDataSource(dataSource); - - ClassPathResource script = new ClassPathResource("scripts/mysql-stored-procedures.sql"); - ResourceDatabasePopulator populator = new ResourceDatabasePopulator(script); - populator.setSeparator(";;"); - initializer.setDatabasePopulator(populator); - - return initializer; - } } } diff --git a/spring-data-jpa/src/test/java/org/springframework/data/jpa/repository/procedures/PostgresStoredProcedureIntegrationTests.java b/spring-data-jpa/src/test/java/org/springframework/data/jpa/repository/procedures/PostgresStoredProcedureIntegrationTests.java index 02e52f9d1..47bcccd99 100644 --- a/spring-data-jpa/src/test/java/org/springframework/data/jpa/repository/procedures/PostgresStoredProcedureIntegrationTests.java +++ b/spring-data-jpa/src/test/java/org/springframework/data/jpa/repository/procedures/PostgresStoredProcedureIntegrationTests.java @@ -19,7 +19,6 @@ package org.springframework.data.jpa.repository.procedures; import static org.assertj.core.api.Assertions.*; import jakarta.persistence.Entity; -import jakarta.persistence.EntityManagerFactory; import jakarta.persistence.GeneratedValue; import jakarta.persistence.Id; import jakarta.persistence.NamedStoredProcedureQuery; @@ -30,14 +29,10 @@ import java.math.BigDecimal; import java.util.List; import java.util.Map; import java.util.Objects; -import java.util.Properties; - -import javax.sql.DataSource; import org.hibernate.dialect.PostgreSQLDialect; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; -import org.postgresql.ds.PGSimpleDataSource; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; @@ -48,15 +43,8 @@ import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.config.EnableJpaRepositories; import org.springframework.data.jpa.repository.query.Procedure; import org.springframework.data.jpa.util.DisabledOnHibernate62; -import org.springframework.jdbc.datasource.init.DataSourceInitializer; -import org.springframework.jdbc.datasource.init.ResourceDatabasePopulator; -import org.springframework.orm.jpa.AbstractEntityManagerFactoryBean; -import org.springframework.orm.jpa.JpaTransactionManager; -import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean; -import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit.jupiter.SpringExtension; -import org.springframework.transaction.PlatformTransactionManager; import org.springframework.transaction.annotation.EnableTransactionManagement; import org.springframework.transaction.annotation.Transactional; @@ -265,7 +253,11 @@ class PostgresStoredProcedureIntegrationTests { @EnableJpaRepositories(considerNestedRepositories = true, includeFilters = @Filter(type = FilterType.ASSIGNABLE_TYPE, classes = EmployeeRepositoryWithRefCursor.class)) @EnableTransactionManagement - static class Config { + static class Config extends StoredProcedureConfigSupport { + + public Config() { + super(PostgreSQLDialect.class, new ClassPathResource("scripts/postgres-stored-procedures.sql")); + } @SuppressWarnings("resource") @Bean(initMethod = "start", destroyMethod = "stop") @@ -274,51 +266,5 @@ class PostgresStoredProcedureIntegrationTests { return new PostgreSQLContainer<>("postgres:15.3") // .withUsername("postgres"); } - - @Bean - public DataSource dataSource(PostgreSQLContainer container) { - - PGSimpleDataSource dataSource = new PGSimpleDataSource(); - dataSource.setUrl(container.getJdbcUrl()); - dataSource.setUser(container.getUsername()); - dataSource.setPassword(container.getPassword()); - return dataSource; - } - - @Bean - public AbstractEntityManagerFactoryBean entityManagerFactory(DataSource dataSource) { - - LocalContainerEntityManagerFactoryBean factoryBean = new LocalContainerEntityManagerFactoryBean(); - factoryBean.setDataSource(dataSource); - factoryBean.setPersistenceUnitRootLocation("simple-persistence"); - factoryBean.setJpaVendorAdapter(new HibernateJpaVendorAdapter()); - factoryBean.setPackagesToScan(this.getClass().getPackage().getName()); - - Properties properties = new Properties(); - properties.setProperty("hibernate.hbm2ddl.auto", "create"); - properties.setProperty("hibernate.dialect", PostgreSQLDialect.class.getCanonicalName()); - factoryBean.setJpaProperties(properties); - - return factoryBean; - } - - @Bean - PlatformTransactionManager transactionManager(EntityManagerFactory entityManagerFactory) { - return new JpaTransactionManager(entityManagerFactory); - } - - @Bean - DataSourceInitializer initializer(DataSource dataSource) { - - DataSourceInitializer initializer = new DataSourceInitializer(); - initializer.setDataSource(dataSource); - - ClassPathResource script = new ClassPathResource("scripts/postgres-stored-procedures.sql"); - ResourceDatabasePopulator populator = new ResourceDatabasePopulator(script); - populator.setSeparator(";;"); - initializer.setDatabasePopulator(populator); - - return initializer; - } } } diff --git a/spring-data-jpa/src/test/java/org/springframework/data/jpa/repository/procedures/PostgresStoredProcedureNullHandlingIntegrationTests.java b/spring-data-jpa/src/test/java/org/springframework/data/jpa/repository/procedures/PostgresStoredProcedureNullHandlingIntegrationTests.java index 565779574..d6c7a1dab 100644 --- a/spring-data-jpa/src/test/java/org/springframework/data/jpa/repository/procedures/PostgresStoredProcedureNullHandlingIntegrationTests.java +++ b/spring-data-jpa/src/test/java/org/springframework/data/jpa/repository/procedures/PostgresStoredProcedureNullHandlingIntegrationTests.java @@ -16,21 +16,17 @@ package org.springframework.data.jpa.repository.procedures; import jakarta.persistence.Entity; -import jakarta.persistence.EntityManagerFactory; import jakarta.persistence.GeneratedValue; import jakarta.persistence.GenerationType; import jakarta.persistence.Id; import java.util.Date; -import java.util.Properties; import java.util.UUID; -import javax.sql.DataSource; - import org.hibernate.dialect.PostgreSQLDialect; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; -import org.postgresql.ds.PGSimpleDataSource; + import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; @@ -41,17 +37,11 @@ import org.springframework.data.jpa.repository.Temporal; import org.springframework.data.jpa.repository.config.EnableJpaRepositories; import org.springframework.data.jpa.repository.query.Procedure; import org.springframework.data.jpa.util.DisabledOnHibernate61; -import org.springframework.jdbc.datasource.init.DataSourceInitializer; -import org.springframework.jdbc.datasource.init.ResourceDatabasePopulator; -import org.springframework.orm.jpa.AbstractEntityManagerFactoryBean; -import org.springframework.orm.jpa.JpaTransactionManager; -import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean; -import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit.jupiter.SpringExtension; -import org.springframework.transaction.PlatformTransactionManager; import org.springframework.transaction.annotation.EnableTransactionManagement; import org.springframework.transaction.annotation.Transactional; + import org.testcontainers.containers.PostgreSQLContainer; /** @@ -138,63 +128,18 @@ class PostgresStoredProcedureNullHandlingIntegrationTests { @EnableJpaRepositories(considerNestedRepositories = true, includeFilters = @ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, classes = TestModelRepository.class)) @EnableTransactionManagement - static class Config { + static class Config extends StoredProcedureConfigSupport { + public Config() { + super(PostgreSQLDialect.class, new ClassPathResource("scripts/postgres-nullable-stored-procedures.sql")); + } + + @SuppressWarnings("resource") @Bean(initMethod = "start", destroyMethod = "stop") public PostgreSQLContainer container() { return new PostgreSQLContainer<>("postgres:15.3") // .withUsername("postgres"); } - - @Bean - public DataSource dataSource(PostgreSQLContainer container) { - - PGSimpleDataSource dataSource = new PGSimpleDataSource(); - dataSource.setUrl(container.getJdbcUrl()); - dataSource.setUser(container.getUsername()); - dataSource.setPassword(container.getPassword()); - - return dataSource; - } - - @Bean - public AbstractEntityManagerFactoryBean entityManagerFactory(DataSource dataSource) { - - LocalContainerEntityManagerFactoryBean factoryBean = new LocalContainerEntityManagerFactoryBean(); - factoryBean.setDataSource(dataSource); - factoryBean.setPersistenceUnitRootLocation("simple-persistence"); - factoryBean.setJpaVendorAdapter(new HibernateJpaVendorAdapter()); - factoryBean.setPackagesToScan(this.getClass().getPackage().getName()); - - Properties properties = new Properties(); - properties.setProperty("hibernate.hbm2ddl.auto", "create"); - properties.setProperty("hibernate.dialect", PostgreSQLDialect.class.getCanonicalName()); - properties.setProperty("hibernate.proc.param_null_passing", "true"); - properties.setProperty("hibernate.globally_quoted_identifiers", "true"); - properties.setProperty("hibernate.globally_quoted_identifiers_skip_column_definitions", "true"); - factoryBean.setJpaProperties(properties); - - return factoryBean; - } - - @Bean - PlatformTransactionManager transactionManager(EntityManagerFactory entityManagerFactory) { - return new JpaTransactionManager(entityManagerFactory); - } - - @Bean - DataSourceInitializer initializer(DataSource dataSource) { - - DataSourceInitializer initializer = new DataSourceInitializer(); - initializer.setDataSource(dataSource); - - ClassPathResource script = new ClassPathResource("scripts/postgres-nullable-stored-procedures.sql"); - ResourceDatabasePopulator populator = new ResourceDatabasePopulator(script); - populator.setSeparator(";;"); - initializer.setDatabasePopulator(populator); - - return initializer; - } } } diff --git a/spring-data-jpa/src/test/java/org/springframework/data/jpa/repository/procedures/StoredProcedureConfigSupport.java b/spring-data-jpa/src/test/java/org/springframework/data/jpa/repository/procedures/StoredProcedureConfigSupport.java new file mode 100644 index 000000000..0b8ef1f9c --- /dev/null +++ b/spring-data-jpa/src/test/java/org/springframework/data/jpa/repository/procedures/StoredProcedureConfigSupport.java @@ -0,0 +1,98 @@ +/* + * Copyright 2024 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 + * + * https://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.procedures; + +import jakarta.persistence.EntityManagerFactory; + +import java.util.Properties; + +import javax.sql.DataSource; + +import org.springframework.context.annotation.Bean; +import org.springframework.core.io.Resource; +import org.springframework.jdbc.datasource.DriverManagerDataSource; +import org.springframework.jdbc.datasource.init.DataSourceInitializer; +import org.springframework.jdbc.datasource.init.ResourceDatabasePopulator; +import org.springframework.orm.jpa.AbstractEntityManagerFactoryBean; +import org.springframework.orm.jpa.JpaTransactionManager; +import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean; +import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter; +import org.springframework.transaction.PlatformTransactionManager; + +import org.testcontainers.containers.JdbcDatabaseContainer; + +/** + * Support class for integration testing with Testcontainers + * + * @author Mark Paluch + */ +class StoredProcedureConfigSupport { + + private final Class dialect; + private final Resource initScript; + + StoredProcedureConfigSupport(Class dialect, Resource initScript) { + this.dialect = dialect; + this.initScript = initScript; + } + + @Bean + DataSource dataSource(JdbcDatabaseContainer container) { + + DriverManagerDataSource dataSource = new DriverManagerDataSource(); + dataSource.setUrl(container.getJdbcUrl()); + dataSource.setUsername(container.getUsername()); + dataSource.setPassword(container.getPassword()); + + return dataSource; + } + + @Bean + AbstractEntityManagerFactoryBean entityManagerFactory(DataSource dataSource) { + + LocalContainerEntityManagerFactoryBean factoryBean = new LocalContainerEntityManagerFactoryBean(); + factoryBean.setDataSource(dataSource); + factoryBean.setPersistenceUnitRootLocation("simple-persistence"); + factoryBean.setJpaVendorAdapter(new HibernateJpaVendorAdapter()); + factoryBean.setPackagesToScan(this.getClass().getPackage().getName()); + + Properties properties = new Properties(); + properties.setProperty("hibernate.hbm2ddl.auto", "create"); + properties.setProperty("hibernate.dialect", dialect.getCanonicalName()); + factoryBean.setJpaProperties(properties); + + return factoryBean; + } + + @Bean + PlatformTransactionManager transactionManager(EntityManagerFactory entityManagerFactory) { + return new JpaTransactionManager(entityManagerFactory); + } + + @Bean + DataSourceInitializer initializer(DataSource dataSource) { + + DataSourceInitializer initializer = new DataSourceInitializer(); + initializer.setDataSource(dataSource); + + ResourceDatabasePopulator populator = new ResourceDatabasePopulator(initScript); + populator.setSeparator(";;"); + initializer.setDatabasePopulator(populator); + + return initializer; + } + +}