36

Note that this code does work with plain Spring but not with Spring Boot(v1.3.3), is there something i'm missing because this is imported from a spring app that works. The code below is from the spring boot app

@Entity
@Table(name="project")
public class Project implements Serializable{

    private static final long serialVersionUID = 1L;

    @Id
    @GeneratedValue(strategy=GenerationType.AUTO)
    @Column(name="id")
    private int id;

    @Column(name="teamId")
    private int teamId;

    //private String Rentabiliteit;

    @Column
    //@Index(name="IProject_status",columnNames="Status")
    private String status;

    @Column
    //@Index(name="IProject_naam",columnNames="Naam")
    private String naam;
    //public Prototype m_Prototype;
    //public Team m_Team;

}

SQL

CREATE TABLE IF NOT EXISTS `project` (
`id` int(11) NOT NULL,
`teamId` int(11) DEFAULT NULL,
`status` varchar(255) DEFAULT NULL,
`naam` varchar(255) DEFAULT NULL
 ) ENGINE=InnoDB AUTO_INCREMENT=43 DEFAULT CHARSET=latin1;

ERROR

Caused by: com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException:           
 Unknown column 'project0_.team_id' in 'field list'

Edited: Application.yml

spring:

mvc:
  view:
    prefix: /WEB-INF/jsp/
    suffix: .jsp

datasource:
    url: jdbc:mysql://localhost:3306/oxyplast
    username: oxyplastuser
    password: oxyplastuserpw

jpa:
  properties:
    hibernate:
      current_session_context_class: org.springframework.orm.hibernate4.SpringSessionContext 
      namingStrategy: org.hibernate.cfg.DefaultNamingStrategy
Aritz
  • 30,971
  • 16
  • 136
  • 217
Thibault Lesuisse
  • 395
  • 1
  • 3
  • 8

7 Answers7

39

SINCE SPRING-BOOT 1.4

Starting from 1.4, because of the switch to Hibernate 5, the naming strategy has been updated to SpringPhysicalNamingStrategy which should be very close to 1.3 defaults.

See also:


PREVIOUS VERSION

Spring Boot provides the ImprovedNamingStrategy as default naming strategy, which makes Hibernate search for a team_id column (inferred from the int teamId field). As this column doesn't exist in your table, that's the cause of the error. From the Hibernate docs:

An improved naming strategy that prefers embedded underscores to mixed case names

You've got two options:

  1. Provide the column name explicitly as @Column(name="teamId"). There used to be a bug with this in early Boot versions, not anymore.

  2. Change the naming strategy in the Spring Boot properties and tell it to use the EJB3NamingStrategy, which doesn't convert camelCase to snake_case, but keeps it as it is.

Fabio Bonfante
  • 5,128
  • 1
  • 32
  • 37
Aritz
  • 30,971
  • 16
  • 136
  • 217
  • I provided the explicid column name, could it be mapped differently by hiberante? Is there a way to see this? – Thibault Lesuisse Apr 06 '16 at 14:23
  • and in my application.yml there is this line – Thibault Lesuisse Apr 06 '16 at 14:25
  • namingStrategy: org.hibernate.cfg.EJB3NamingStrategy – Thibault Lesuisse Apr 06 '16 at 14:25
  • Well i tried to change the name in the database and then it says that the entity is not mapped – Thibault Lesuisse Apr 06 '16 at 14:30
  • 1
    I've solved the problem by renaming it teamid ( without capital I )! Thanks a lot for the partience and help – Thibault Lesuisse Apr 06 '16 at 14:55
  • 3
    add these properties solved it for me: --spring.jpa.hibernate.naming.implicit-strategy=org.hibernate.boot.model.naming.ImplicitNamingStrategyLegacyJpaImpl --spring.jpa.hibernate.naming.physical-strategy=org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl – ozOli Aug 29 '16 at 19:17
  • 2
    I solved the problem by adding this line in the file application.properties: spring.jpa.hibernate.naming.physical-strategy=org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl – d9daniel Sep 20 '17 at 09:50
  • How do you configure projections: i.e when mapping java interface to SQL views? I have a table with a lot of columns and renaming them in the view just seems like a bad way to do it. Currently it's allowing underscores but the interface will not pick it up. They have to match 100% – TheRealChx101 Sep 10 '21 at 06:32
  • Hello, @TheRealChx101, it's been a while since I don't do Hibernate, but working with views should be exactly the same as with tables. However, be careful with views involving expensive queries, most engines such as MySql don't cache them: https://stackoverflow.com/questions/4789332/is-a-mysql-view-faster-than-a-normal-query – Aritz Sep 10 '21 at 06:45
  • @XtremeBiker I'm using PostgreSQL. The views work without issue but the interface's `getXXX` methods must exactly match the column names. i.e: a view with `id, first_name, last_name` will not match `getFirstName(), getLastName()`, but will match `getFirst_Name(), getLast_Name()`. On the other hand, an entity will match. So, as you can see, in order for the projection to match, I have to write the view with camel case naming, which means selecting the columns from the tables individually. – TheRealChx101 Sep 10 '21 at 06:57
26

If you are using Spring Boot 2.0.2 and Hibernate 5.3.4 then setting the following property will fix the issue.

spring.jpa.hibernate.naming.physical-strategy=org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl
Zoe
  • 27,060
  • 21
  • 118
  • 148
Damodar P
  • 1,283
  • 8
  • 3
  • I tried the same in my project it is not working. I have posted my question in this link https://stackoverflow.com/questions/61010482/oracle-jdbc-oracledatabaseexception-ora-00972-identifier-is-too-long – JAVA_CAT Apr 03 '20 at 12:16
1

Below strategy worked for me

spring.jpa.hibernate.naming-strategy = org.hibernate.cfg.DefaultComponentSafeNamingStrategy
Sagar U
  • 86
  • 4
  • 2
    spring.jpa.hibernate.naming-strategy does not exists in latest version this solution might work but will not in the latest version. – Rafael Nov 01 '18 at 13:27
0

with the late version :

    spring-boot-starter-data-jpa: ➡ 1.5.2.RELEASE
    hibernate-core:5.0.12.Final

this class

PhysicalNamingStrategyStandardImpl

needs to be extended and added to hibernate properties.

Here is a full working version

    public class PhysicalNamingStrategyImpl extends PhysicalNamingStrategyStandardImpl implements Serializable {

    public static final PhysicalNamingStrategyImpl INSTANCE = new PhysicalNamingStrategyImpl();

    @Override
    public Identifier toPhysicalTableName(Identifier name, JdbcEnvironment context) {
        String nameModified;
        // Do whatever you want with the name modification
        return new Identifier(nameModified, name.isQuoted());
    }

}

    @Override
    public Identifier toPhysicalColumnName(Identifier name, JdbcEnvironment context) {
         String nameModified;
        // Do whatever you want with the name modification
        return new Identifier(nameModified, name.isQuoted());
    }

Linking it to hibernate should be done like this when configuring the datasource.

properties.put("hibernate.physical_naming_strategy", "my.Package.PhysicalNamingStrategyImpl");

here is a full working version of datasource config

import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.jdbc.DataSourceBuilder;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.orm.jpa.EntityManagerFactoryBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;

import javax.persistence.EntityManagerFactory;
import javax.sql.DataSource;
import java.util.HashMap;
import java.util.Map;


@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(
        entityManagerFactoryRef = "entityManagerFactory",
        basePackages = { "com.xxxxxx.repository" }
)
public class SharedDataSourceConfig {

    @Value("${startup.ddl-auto}")
    String hbm2ddl;

    @Primary
    @Bean(name = "dataSource")
    @ConfigurationProperties("spring.datasource.shared")
    public DataSource customerDataSource() {
        return DataSourceBuilder.create().build();
    }

    @Primary
    @Bean(name = "entityManagerFactory")
    public LocalContainerEntityManagerFactoryBean entityManagerFactory(
            EntityManagerFactoryBuilder builder,
            @Qualifier("dataSource") DataSource dataSource) {
        Map<String, Object> properties = new HashMap<String, Object>();
        properties.put("hibernate.hbm2ddl.auto", hbm2ddl);
        properties.put("hibernate.physical_naming_strategy", "my.package.PhysicalNamingStrategyImpl");
        return builder
                .dataSource(dataSource)
                .packages(PackageScannerHelper.getPackagesToScan())
                .persistenceUnit("shared")
                .properties(properties)
                .build();
    }

    @Primary
    @Bean(name = "transactionManager")
    public PlatformTransactionManager transactionManager(
            @Qualifier("entityManagerFactory") EntityManagerFactory
                    entityManagerFactory
    ) {
        return new JpaTransactionManager(entityManagerFactory);
    }
}
Toumi
  • 2,925
  • 4
  • 37
  • 31
0

This worked for me with spring boot 1.4.0 and hibernate entitymanager 4.3.8.Final

application.properties

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

Vivek Goel
  • 762
  • 2
  • 10
  • 21
0

application.properties

spring.jpa.hibernate.naming-strategy = org.hibernate.cfg.DefaultComponentSafeNamingStrategy

the above properties work for me. hibernate 4.3.11.Final spring boot 1.4.2.RELEASE

abu kalam azad
  • 161
  • 1
  • 4
0

Spring boot 3

spring:
  jpa:
    open-in-view: false
    show-sql: true
    database-platform: org.hibernate.dialect.H2Dialect
    hibernate:
      naming:
        physical-strategy: org.hibernate.boot.model.naming.CamelCaseToUnderscoresNamingStrategy
        implicit-strategy: org.springframework.boot.orm.jpa.hibernate.SpringImplicitNamingStrategy
  • physical-strategy: org.hibernate.boot.model.naming.CamelCaseToUnderscoresNamingStrategy
  • implicit-strategy: org.springframework.boot.orm.jpa.hibernate.SpringImplicitNamingStrategy
Flavio Oliva
  • 401
  • 4
  • 15