Проблема с именованием полей Hibernate с помощью Spring Загрузка (стратегия именования)

Обратите внимание, что этот код работает с обычным Spring, но не с Spring Boot (v1.3.3), есть что-то, чего я не вижу, потому что он импортируется из приложения Spring, которое работает. Ниже приведен код из загрузочного приложения Spring

@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;

ОШИБКА

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

Отредактировано: 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

Ответ 1

Spring Boot предоставляет ImprovedNamingStrategy качестве стратегии именования по умолчанию, которая позволяет Hibernate искать столбец team_id (выводится из поля int teamId). Поскольку этот столбец не существует в вашей таблице, это причина ошибки. Из документов Hibernate:

Улучшенная стратегия именования, которая предпочитает встроенные подчеркивания смешанным именам

У вас есть два варианта:

  1. Укажите имя столбца в явном виде как @Column(name="teamId"). Раньше была ошибка с этим в ранних версиях Boot, больше нет.

  2. Измените стратегию именования в свойствах Spring Boot и попросите его использовать EJB3NamingStrategy, который не конвертирует camelCase в snake_case, но сохраняет его как есть.


Обновить

Начиная с версии 1.4, из-за перехода на Hibernate 5 стратегия именования была обновлена до SpringPhysicalNamingStrategy которая должна быть очень близка к значениям по умолчанию 1.3.

Смотрите также:

Ответ 2

Ниже стратегия работала для меня

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

Ответ 3

с поздней версией:

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

этот класс

PhysicalNamingStrategyStandardImpl

необходимо расширить и добавить в свойства спящего режима.

Вот полная рабочая версия

    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());
    }

Связывание с hibernate должно выполняться следующим образом при настройке источника данных.

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

Вот полная рабочая версия конфигурации datasource

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);
    }
}

Ответ 4

Если вы используете Spring Boot 2.0.2 и Hibernate 5.3.4, то установка следующего свойства решит проблему.

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

Ответ 5

Если вы используете Spring Boot 2.0.2 и Hibernate 5.3.4, то при установке следующего свойства в hibernate будут использоваться имена столбцов базы данных camelCase.

spring.jpa.hibernate.naming.physical-стратегия = org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl

-damodar

Ответ 6

если вы хотите использовать UpperCase в имени столбца, вы должны использовать его таким образом

@Column(name="\"teamId\"")

private int teamId;

вам нужно принудительно спящий режим, даже используя EJB3NamingStrategy или ImprovedStrategyNaming.