Hibernate field naming issue with Spring Boot (naming strategy)

后端 未结 6 900
粉色の甜心
粉色の甜心 2020-11-29 09:31

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

相关标签:
6条回答
  • 2020-11-29 09:33

    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:

    • Spring's naming strategy

    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.

    0 讨论(0)
  • 2020-11-29 09:34

    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

    0 讨论(0)
  • 2020-11-29 09:38

    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
    
    0 讨论(0)
  • 2020-11-29 09:41

    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

    0 讨论(0)
  • 2020-11-29 09:49

    Below strategy worked for me

    spring.jpa.hibernate.naming-strategy = org.hibernate.cfg.DefaultComponentSafeNamingStrategy
    
    0 讨论(0)
  • 2020-11-29 09:53

    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);
        }
    }
    
    0 讨论(0)
提交回复
热议问题