I have this JPA configuration class which is in the regular classpath (not in test classpath) and I don't want to duplicate it (I don't want one copy for runtime, and one copy for test) :
@Configuration
@EnableTransactionManagement
@PropertySource("classpath:persistence-${env:int}.properties")
@EnableJpaRepositories(basePackages = "fr.tristan.demoassurance.infrastructure.repository.mysql")
@SuppressWarnings("unused")
public class PersistenceJpaConfig {
@Bean
LocalContainerEntityManagerFactoryBean entityManagerFactory(Environment env) {
final LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
em.setDataSource(dataSource(env));
em.setPackagesToScan("fr.tristan.demoassurance.infrastructure.repository.mysql.entity");
final JpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
em.setJpaVendorAdapter(vendorAdapter);
em.setJpaProperties(additionalProperties(env));
return em;
}
@Bean
DataSource dataSource(Environment env) {
final DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName(Preconditions.checkNotNull(env.getProperty("jdbc.driverClassName")));
dataSource.setUrl(Preconditions.checkNotNull(env.getProperty("jdbc.url")));
dataSource.setUsername(Preconditions.checkNotNull(env.getProperty("jdbc.user")));
dataSource.setPassword(Preconditions.checkNotNull(env.getProperty("jdbc.pass")));
return dataSource;
}
@Bean
PlatformTransactionManager transactionManager(Environment env) {
final JpaTransactionManager transactionManager = new JpaTransactionManager();
transactionManager.setEntityManagerFactory(entityManagerFactory(env).getObject());
return transactionManager;
}
@Bean
PersistenceExceptionTranslationPostProcessor exceptionTranslation() {
return new PersistenceExceptionTranslationPostProcessor();
}
final Properties additionalProperties(Environment env) {
final Properties hibernateProperties = new Properties();
hibernateProperties.setProperty("hibernate.hbm2ddl.auto", env.getProperty("hibernate.hbm2ddl.auto"));
hibernateProperties.setProperty("hibernate.hbm2ddl.import_files", env.getProperty("hibernate.hbm2ddl.import_files"));
hibernateProperties.setProperty("hibernate.dialect", env.getProperty("hibernate.dialect"));
hibernateProperties.setProperty("hibernate.cache.use_second_level_cache", env.getProperty("hibernate.cache.use_second_level_cache"));
hibernateProperties.setProperty("hibernate.cache.use_query_cache", env.getProperty("hibernate.cache.use_query_cache"));
return hibernateProperties;
}
}
It relies on 2 properties file, only one is loaded using -Denv=int or -Denv=dev (or just no param since "int" is the default env value) :
- persistence-dev.properties
- persistence-int.properties
If I put my H2 dependency in "test" scope instead of the default "compile" scope,
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<scope>test</scope>
</dependency>
and I run my tests using mvn clean verify -Denv=dev
, I get this error :
2023-05-31T13:04:27.200+02:00 ERROR 17240 --- [ main] o.s.test.context.TestContextManager : Caught exception while allowing TestExecutionListener [org.springframework.test.context.web.ServletTestExecutionListener] to prepare test instance [fr.tristan.demoassurance.DemoAssuranceServiceIntegrationTest@578483bd]
(...)
Caused by: java.lang.IllegalStateException: Could not load JDBC driver class [org.h2.Driver]