15

I'm a little bit confused by hibernates (version 5.1) naming strategy - namely it changes my table name and I'd like to avoid that. Also - spring.jpa.hibernate.naming_strategy seems to be deprecated according to intelij, but I can't find a (nother) way of configuring it correctly.

I have the following configuration in application.properties:

spring.jpa.hibernate.naming_strategy=org.hibernate.cfg.EJB3NamingStrategy
spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.MySQL5Dialect
spring.jpa.properties.hibernate.enable_lazy_load_no_trans=true
spring.jpa.properties.hibernate.current_session_context_class=thread

The first one is marked as depracted, as said.

Now I have an entity:

@Entity
@Table(name = "usaUploadTable", schema = "usertable201", catalog = "")
public class UsaUploadTable {
    ....
}

The table name is, like in @Table(name = "") usaUploadTable.

Now when I run my application, I get

Table 'usertable201.usa_upload_table' doesn't exist

which is correct - it isn't named like how hibernate is changing it.

What can I do to make hibernate use my table name correctly?

Edit:

I've also tried

DefaultNamingStrategy
ImprovedNamingStrategy

All of them change it

Versions:

spring-boot-1.4.0.RELEASE
hibernate 5.1
javax-transaction-api 1.2
hibernate-validator 5.2.4
javassist 3.20
  • This github thread is useful for both Hibernate 4 n 5 . https://github.com/spring-projects/spring-boot/issues/2129 – Nikhil Sahu Oct 10 '17 at 07:36

5 Answers5

12
spring.jpa.hibernate.naming.physical-strategy=org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl

it worked for me. here are the versions i'm using:

Spring Boot (v1.4.2.RELEASE)
Hibernate Core {5.0.11.Final}
rsinha
  • 683
  • 6
  • 9
10

The problem lies in spring-boot-1.4 - it seems like they have changed the properties (or whatever) I've now found this answer ImprovedNamingStrategy no longer working in Hibernate 5, but it still didn't resolve correctly. So I have changed the code a little to not use the underscore method and to extend the newly introduced class SpringPhysicalNamingStrategy:

package com.foo;

import org.hibernate.boot.model.naming.Identifier;
import org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl;
import org.hibernate.engine.jdbc.env.spi.JdbcEnvironment;

import java.io.Serializable;
import java.util.Locale;


public class RealNamingStrategyImpl extends org.springframework.boot.orm.jpa.hibernate.SpringPhysicalNamingStrategy implements Serializable {

    public static final PhysicalNamingStrategyImpl INSTANCE = new PhysicalNamingStrategyImpl();

    @Override
    public Identifier toPhysicalTableName(Identifier name, JdbcEnvironment context) {
        return new Identifier(name.getText(), name.isQuoted());
    }

    @Override
    public Identifier toPhysicalColumnName(Identifier name, JdbcEnvironment context) {
        return new Identifier(name.getText(), name.isQuoted());
    }

}

And in application.properties I've changed the deprecated line to

spring.jpa.properties.hibernate.physical_naming_strategy=<package>.RealNamingStrategyImpl

Now it uses exactly the table and column names as I have them in my entity files.

Community
  • 1
  • 1
  • Is there a way to define the `NamingStrategy` over a Java config instead with the properties file? Obviously, that's a configuration that most probably won't change at all. Therefor I'd like to have that hard coded. – Herr Derb Sep 26 '17 at 09:28
  • 1
    Golden! This is what I was looking for. Two tweaks ``1) public static final PhysicalNamingStrategyImpl INSTANCE = new PhysicalNamingStrategyImpl(); `` should be ``public static final PhysicalNamingStrategyStandardImpl INSTANCE = new PhysicalNamingStrategyStandardImpl();`` ``2) remove `import java.util.Locale;`` – Forrest Jan 14 '19 at 06:13
  • Here we are 6 years later and this issue still comes up and this is the correct answer – markyk Nov 13 '22 at 08:34
2

For one who wants to upper case in Postgresql and Spring boot 1.5.2

public class CustomDatabaseIdentifierNamingStrategy extends org.springframework.boot.orm.jpa.hibernate.SpringPhysicalNamingStrategy implements Serializable {

    public static final long serialVersionUID = 1L;
    public static final CustomDatabaseIdentifierNamingStrategy INSTANCE = new CustomDatabaseIdentifierNamingStrategy();

    @Override
    public Identifier toPhysicalTableName(Identifier name, JdbcEnvironment context) {
        return new Identifier(name.getText().toUpperCase(), true);
    }

    @Override
    public Identifier toPhysicalColumnName(Identifier name, JdbcEnvironment context) {
        return new Identifier(name.getText().toUpperCase(), true);
    }

}
Kerem Baydoğan
  • 10,475
  • 1
  • 43
  • 50
Bằng Rikimaru
  • 1,512
  • 2
  • 24
  • 50
  • 1
    Be careful when running the above code on a Turkish server. `toUpperCase()` will convert `items` to `İTEMS` (latin capital letter i with dot above). To fix this, always use `toUpperCase(Locale.ROOT)`. – Roland Illig Jan 02 '18 at 15:46
2

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
-1

Spring boot 2.0.0 & Hibernate 5

    public class MySqlNamingStrategyImpl extends org.springframework.boot.orm.jpa.hibernate.SpringPhysicalNamingStrategy implements Serializable {

protected boolean isCaseInsensitive(JdbcEnvironment jdbcEnvironment) {
    return false;
}

}

Igor Azarny
  • 124
  • 1
  • 3