A0__oN
A0__oN

Reputation: 9100

Hibernate 5.1.x naming Strategy (backward compatible with Hibernate 4.x)

I'm using Spring Boot 1.3.3.RELEASE. By default Spring Boot uses the Hibernate Version 4.x. I'm trying to use new Hibernate i.e 5.1.0 FINAL (as of now).

I'm using Gradle so to override the Hibernate Version I've added the following line

ext['hibernate.version']="5.1.0.Final"

followed the steps of SpringBoot 1.3.0 support hibernate 5?

I'm using following for naming Strategy

spring.jpa.properties.hibernate.naming.implicit-strategy: org.hibernate.boot.model.naming.ImplicitNamingStrategyLegacyHbmImpl

spring.jpa.properties.hibernate.naming.physical_strategy: org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl

I've have a Entity class

@Entity
public class AppUser {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @NotNull
    @Length(max = 100)
    private String username;

    @NotNull
    @Length(max = 100)
    private String firstName;

    @NotNull
    @Length(max = 100)
    private String lastName;

    @Length(max = 100)
    private String middleName;

    @NotNull
    @Length(max=100)
    private String email;

    @NotNull
    @Length(max = 100)
    private String password;

    @NotNull
    private boolean enabled;

}

On Hibernate 4.x it executes the query

create table app_user (
        id bigint not null auto_increment,
        email varchar(100) not null,
        enabled bit not null,
        first_name varchar(100) not null,
        last_name varchar(100) not null,
        middle_name varchar(100),
        password varchar(100) not null,
        username varchar(100) not null,
        primary key (id)
    )

on 5.x it executed the query

create table AppUser (
        id bigint not null auto_increment,
        email varchar(100) not null,
        enabled bit not null,
        firstName varchar(100) not null,
        lastName varchar(100) not null,
        middleName varchar(100),
        password varchar(100) not null,
        username varchar(100) not null,
        primary key (id)
    )

How can I set the naming strategy such that Hibernate Uses 5.x underscore (as 4.x) on Table name and Column Name

Upvotes: 4

Views: 8096

Answers (2)

Raj Kundalia
Raj Kundalia

Reputation: 113

I am providing my analysis for anyone to use:

If you are providing @Table and @Column annotation in your entity classes with names provided with an underscore i.e. user_id i.e. @Column(name="user_id"), it will take the column name as user_id; if you give it as userid then it will change to user_id if you use no strategy or implicit strategy (specifically spring.jpa.hibernate.naming.implicit-strategy=org.hibernate.boot.model.naming.ImplicitNamingStrategyLegacyHbmImpl). So, if you want a strategy where the entity attribute name changes to one with underscore and lowercase letters i.e. something from userId to user_id, you should use implicit or no strategy (which actually uses implicit strategy).

If you don't want your naming strategy to add an underscore to the column name or class name, then the strategy that you need to use would look like: spring.jpa.hibernate.naming.physical-strategy=org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl. The things that you provide in annotations @Table and @Column’s name attribute would remain as it is.

If you don't want to provide annotations and want to manually handle the table name and column names, you should extend the class org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl and override the required methods. If you still use annotations for some of the cases here, remember the overridden methods will apply on the names written in those annotations. spring.jpa.hibernate.naming.physical-strategy=example.CustomStrategy

Upvotes: 0

v.ladynev
v.ladynev

Reputation: 19956

Firstly, you don't need org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl

because of it does nothing and is used by Hibernate as default.

Hibernate 5 doesn't have a strategy that you want. All strategies are JPA compliant (generate names like AppUser). So you need to implement your own.

For an example a physical naming strategy

public class UnderscorePhysicalStartegy extends PhysicalNamingStrategyStandardImpl {

    @Override
    public Identifier toPhysicalTableName(Identifier name, JdbcEnvironment context) {
        return context.getIdentifierHelper()
                .toIdentifier(NamingStrategyUtils.classToName(name.getText()));
    }

}

It uses NamingStrategyUtils.

Keep in mind, if you specify an explicit name

@Entity
@Table(name = "AppUser")
public class AppUser {

}

you will have anyway a table name app_user. If you don't want such behavior use an implicit naming strategy.

I did some research work on naming strategies. You can refer Hibernate5NamingStrategy, it generates table and column names with underscores like you need and constraint names (unique, foreign key) as well.

This class is used to generate names: HibernateNamingStrategy.

How to use Hibernate5NamingStrategy

The naming strategy can be configured using StrategyOptions.

For example, to use strategy without the prefixes (like f_):

StrategyOptions options = StrategyOptions.builder().withoutPrefixes().build();
Hibernate5NamingStrategy strategy = new Hibernate5NamingStrategy(options);

Other examples: Hibernate 5 Implicit Naming Strategy

Except that, ImprovedNamingStrategy for Hibernate 5 can be used to simulate the behaviour of Hibernate 4 ImprovedNamingStrategy.

Upvotes: 5

Related Questions