4

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

Community
  • 1
  • 1
A0__oN
  • 8,740
  • 6
  • 40
  • 61
  • Are you sure you have changed the hibernate version to 5.1.0 with `ext['hibernate.version']="5.1.0.Final"`? I think the solution in the link you have reference works for maven but not for gradle. – TheKojuEffect May 06 '16 at 03:11
  • yes. when Classpath includes the hibernate 5.1.0.Final Jars – A0__oN May 06 '16 at 03:12

2 Answers2

5

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.

v.ladynev
  • 19,275
  • 8
  • 46
  • 67
  • Any way to us it without the `f_` prefix? Annoying as hell for a default setting. – Bassinator Nov 04 '17 at 22:00
  • @Airhead I updated my answer. I don't know which the default behaviour better to use. – v.ladynev Nov 05 '17 at 12:58
  • I ended up creating my own class which extends the mentioned class and configures the options that way, in order to be able to use it from the persistence.xml instead of the deprecated configuration object. – Bassinator Nov 05 '17 at 16:19
  • 1
    @Airhead That's interesting. It will need to add this way to the documentation. – v.ladynev Nov 05 '17 at 20:39
0

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

Raj Kundalia
  • 73
  • 2
  • 8