lundi 9 novembre 2020

@SpringBootTest - hibernate physical naming strategy is ignored only for tests

My question is why is physical-strategy ignored here for test environment? I have tried all standard implementations and have implemented my own naming strategy. I used the old definition of hibernate 4 for naming strategies and the new one since hibernate 5 as seen in this example. Only the naming of the real database is affected. If I change the naming strategy, the naming of the test database entities is always defined in snake case. e.g.: user_membership This behaviour is annoying as we create test data via sql scripts on the servers as well for JUnit integration tests. Also we have some native sql files for long running exports to improve performance, which we can't test properly if both naming strategies don't match.

I finally decided to use a custom snake case strategy for all new backend server I'll implement to have same naming in test and real database, but for all old backend server I can't change the existing strategy, because of existing database in production.

I use:

  • Spring Boot: 2.2.5.RELEASE
    • spring-boot-starter-web
    • spring-boot-starter-test
    • spring-boot-starter-data-jpa
  • Hibernate: 5.3.15.Final

application.yml for server execution:

spring:
  resources:
    add-mappings: true
  velocity:
    enabled: false
  profiles:
    active: @spring.profiles.active@
  datasource:
    url: jdbc:mysql://${spring.datasource.endpoint}:${spring.datasource.port}/${spring.datasource.name}?useUnicode=true&characterEncoding=utf8&useSSL=false
    username: ${/web-backend-[stage]/app/database/user}
    password: ${/web-backend-[stage]/app/database/password}
    endpoint: ${/web-backend-[stage]/app/database/endpoint}
    port: ${/web-backend-[stage]/app/database/port}
    name: ${/web-backend-[stage]/app/database/name}
  jpa:
    database-platform: org.hibernate.dialect.MySQL5InnoDBDialect
    database: MYSQL
    openInView: false
    show_sql: false
    generate-ddl: false
    hibernate:
      ddl-auto: validate
      naming:
        physical-strategy: org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl

application-test.yml for server execution:

spring:
  velocity:
    enabled: false
  profiles:
    active: test
  datasource:
    dataSourceClassName: org.h2.jdbcx.JdbcDataSource
    url: jdbc:h2:mem:test;MODE=MYSQL;DB_CLOSE_DELAY=-1
    databaseName:
    serverName:
    username:
    password:

  jpa:
    database-platform: org.hibernate.dialect.MySQL5InnoDBDialect
    database: MYSQL
    openInView: false
    show_sql: false
    generate-ddl: true
    hibernate:
      ddl-auto: create
      naming:
        physical-strategy: org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl

BaseIntegrationTest.class

import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
import org.springframework.test.context.ActiveProfiles;
import org.springframework.test.context.jdbc.Sql;

@SuppressWarnings("ClassMayBeInterface") // must be class to inherit annotations
@ActiveProfiles(SpringProfile.TEST)
@Sql({"/db/clean.sql", "/db/data.sql"})
@SpringBootTest(webEnvironment = WebEnvironment.DEFINED_PORT, classes = {Application.class, TestDataProvider.class})
public abstract class BaseIntegrationTest {

}

in every test:

@Autowired
private WebApplicationContext wac;

@PostConstruct
void setup() {
    MockitoAnnotations.initMocks(this);

    restProjectMockMvc = MockMvcBuilders.webAppContextSetup(wac)
       .apply(springSecurity())
       .build();
}

Aucun commentaire:

Enregistrer un commentaire