Denis Stephanov
Denis Stephanov

Reputation: 5231

Naming strategy of columns in spring boot 2

how can I configure spring to using underscore in columns without explicitly defined in @Column? For instance if I have column in entity like this:

@LastModifiedBy
private String changedBy;

I want to map it to physical column in database which is changed_by

I tried to configure it with property spring.jpa.hibernate.naming.physical-strategy to SpringPhysicalNamingStrategy or PhysicalNamingStrategyStandardImpl but I always got exception ERROR: column "changedby" of relation "xxxx" does not exist

Upvotes: 5

Views: 2665

Answers (3)

Dirk Bolte
Dirk Bolte

Reputation: 662

In my setup (Postgres, Flyway), I achieve this using the hybernate-types package: https://github.com/vladmihalcea/hibernate-types . This will give you a ready-to-use implementation for the naming strategy: CamelCaseToSnakeCaseNamingStrategy

You can configure this in XML like this:

<property name="hibernate.physical_naming_strategy"
value="com.vladmihalcea.hibernate.type.util.CamelCaseToSnakeCaseNamingStrategy"/>

Alternatively, you can configure it in code (Kotlin in my case):


@Bean
fun entityManagerFactory(): LocalContainerEntityManagerFactoryBean {
    val jpaProperties = Properties().apply {
        put("hibernate.physical_naming_strategy", CamelCaseToSnakeCaseNamingStrategy::class.java.canonicalName)
        // ....
    }
    return LocalContainerEntityManagerFactoryBean().apply {
        setJpaProperties(properties)
        // ....
    }

See also https://vladmihalcea.com/map-camel-case-properties-snake-case-column-names-hibernate/ for further information.

Upvotes: 3

Ori Marko
Ori Marko

Reputation: 58774

You can use custom naming for snake case

we can tell Hibernate to use our new strategy:

hibernate.physical_naming_strategy=com.baeldung.hibernate.namingstrategy.CustomPhysicalNamingStrategy

public class CustomPhysicalNamingStrategy implements PhysicalNamingStrategy {     
    @Override
    public Identifier toPhysicalCatalogName(final Identifier identifier, final JdbcEnvironment jdbcEnv) {
        return convertToSnakeCase(identifier);
    }     
    @Override
    public Identifier toPhysicalColumnName(final Identifier identifier, final JdbcEnvironment jdbcEnv) {
        return convertToSnakeCase(identifier);
    }     
    @Override
    public Identifier toPhysicalSchemaName(final Identifier identifier, final JdbcEnvironment jdbcEnv) {
        return convertToSnakeCase(identifier);
    }     
    @Override
    public Identifier toPhysicalSequenceName(final Identifier identifier, final JdbcEnvironment jdbcEnv) {
        return convertToSnakeCase(identifier);
    }     
    @Override
    public Identifier toPhysicalTableName(final Identifier identifier, final JdbcEnvironment jdbcEnv) {
        return convertToSnakeCase(identifier);
    }     
    private Identifier convertToSnakeCase(final Identifier identifier) {
        final String regex = "([a-z])([A-Z])";
        final String replacement = "$1_$2";
        final String newName = identifier.getText()
          .replaceAll(regex, replacement)
          .toLowerCase();
        return Identifier.toIdentifier(newName);
    }
}

Upvotes: 2

Frank
Frank

Reputation: 112

You could use @Column to manually specify the name of your column:

     @LastModifiedBy
     @Column(name="changed_by")
     private String changedBy;

Upvotes: 1

Related Questions