2

I have MySQL with tables in two databases and want to write a test with SpringBoot (1.5.6.RELEASE) and JPA. For this, I use the @DataJpaTest together with @EntityScan, as the entities are in two different packages. As embedded database for the test, I use H2.

  1. My first problem was, that Spring Boot threw an exception that the schemas were not found, therefore I created a schema.sql with two CREATE SCHEMA IF NOT EXISTS statements like described in this question.
  2. However, I also wanted to insert some test data and added a data.sql file. The problem was now, that Spring boot first executed the schema.sql, then the data.sql and following this Hibernate again created the tables, which eventually resulted in empty tables. To solve this problem, I tried to set spring.jpa.hibernate.ddl-auto=none within the application.properties. However, Hibernate now started to switch naming strategies and converted camelCase to sneak_case, which again resulted in errors. So I guess, this is not the way how it should be done. I also tried spring.jpa.generate-ddl=false, but this did not have any effect.

How is it possible to deactivate the automatic DDL generation (only use schema.sql and data.sql) and at the same time use @DataJpaTest?

Thank you very much!

Emad
  • 769
  • 9
  • 21
Rolch2015
  • 1,354
  • 1
  • 14
  • 20

2 Answers2

3

Solution 1: properties/yaml file

spring:
 autoconfigure:
  exclude: org.springframework.boot.autoconfigure.security.SecurityAutoConfiguration
 jackson:
  serialization:
   indent_output: true
 datasource:
  driver-class-name: org.hsqldb.jdbcDriver
  generate-unique-name: true
 jpa:
  hibernate:
    ddl-auto: none
  show-sql: true
 h2:
  console:
   enabled: false

liquibase:
 change-log: classpath:/liquibase/db.changelog-master.xml
 drop-first: true
 contexts: QA

Solution 2: override @Bean

@Bean
LocalContainerEntityManagerFactoryBean entityManagerFactory(DataSource dataSource, Environment env) {
    final LocalContainerEntityManagerFactoryBean factory = new LocalContainerEntityManagerFactoryBean();
    factory.setDataSource(dataSource);
    factory.setJpaVendorAdapter(new HibernateJpaVendorAdapter());
    factory.setPackagesToScan("com.spring.web.demo.persistent.entity");
    factory.setJpaProperties(jpaProperties(env));

    return factory;
}

private Properties jpaProperties(Environment env) {
    final Properties properties = new Properties();
    properties.put("hibernate.dialect", env.getRequiredProperty("hibernate.dialect"));
    //!!!: see here
    properties.put("hibernate.hbm2ddl.auto", "none");

    properties.put("hibernate.show_sql", env.getRequiredProperty("hibernate.show_sql"));
    properties.put("hibernate.format_sql", false);
    properties.put("hibernate.physical_naming_strategy", PhysicalNamingStrategyStandardImpl.class.getName());
    properties.put("hibernate.generate_statistics", true);
    properties.put("hibernate.cache.use_second_level_cache", true);
    properties.put("hibernate.cache.use_query_cache", true);
    properties.put("hibernate.cache.region.factory_class", "org.hibernate.cache.ehcache.EhCacheRegionFactory");

    return properties;
}

Note, that application.properies or application.yaml should be under test/resources and your @Configuration class with @Bean should be used by tests.

For test via sql-files you could use EmbeddedDataSource

There are some examples at my github

Eugene Ustimenko
  • 322
  • 4
  • 16
  • Thank you for your answer. As mentioned in my question, setting `ddl-auto=none` does not work. Your third solution is not what I aimed at with my question. However, I found out that adding `spring.jpa.hibernate.naming.physical-strategy=org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl` additionaly to ``ddl-auto=none` seems to be an acceptable workaround. If you change your first and second solution accordingly I can mark it as accepted answer. Unfortunaqtely, your github link does not help, can you provide a more specific link? Thank you! – Rolch2015 Aug 03 '17 at 21:09
  • Change GitHub link to the example of test repositories. – Eugene Ustimenko Aug 04 '17 at 04:41
  • your answer still is not corresponding to my question. I neither use liquibase nor HSQLDB, Your desribed solution does not work for me. The workaround which works is setting `spring.jpa.hibernate.naming.physical-strategy=org.hibernate.‌​boot.model.naming.Ph‌​ysicalNamingStrategy‌​StandardImpl` and `ddl-auto=none` – Rolch2015 Aug 07 '17 at 00:30
1

you can create another application.properties and configure file for under test directory.

for other problem use flyway after db creation flyway scripts which is your insert scripts run automatically.

eyupaksu
  • 251
  • 3
  • 7
  • I have an `application.properties` file in my test directory, how should I configure it? Could you be a bit more specific how to get flyway to work together with `@DataJpaTest`? – Rolch2015 Aug 03 '17 at 21:11
  • you can add as dependency also you should add a plugin and when you create dbS once, export create scripts and fill flyway files what is extension .sql already. and below the create scripts add your insert script, and set hibernate ddl-auto: none or false this script file runs before the app stand up, and your db is gonna ready – eyupaksu Aug 04 '17 at 09:46