Reputation: 9100
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
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
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