Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/html/82.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
spring-Hibernate5命名策略配置_Spring_Configuration_Hibernate 5.x - Fatal编程技术网

spring-Hibernate5命名策略配置

spring-Hibernate5命名策略配置,spring,configuration,hibernate-5.x,Spring,Configuration,Hibernate 5.x,我正在使用postgresql数据库和spring+hibernate框架编写应用程序 我将spring框架从4.1.5.RELEASE升级到4.2.0.RELEASE版本,并将hibernate框架从4.3.7.Final升级到5.0.0.Final版本 升级后,我的NamingStrategy出现问题。在postgresql数据库中,表列名是小写的,用下划线分隔,在应用层中,bean属性是大写的 这是旧版本的spring配置文件: <?xml version="1.0" encodin

我正在使用postgresql数据库和spring+hibernate框架编写应用程序

我将spring框架从4.1.5.RELEASE升级到4.2.0.RELEASE版本,并将hibernate框架从4.3.7.Final升级到5.0.0.Final版本

升级后,我的NamingStrategy出现问题。在postgresql数据库中,表列名是小写的,用下划线分隔,在应用层中,bean属性是大写的

这是旧版本的spring配置文件:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns="http://www.springframework.org/schema/beans"
       xmlns:p="http://www.springframework.org/schema/p"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:tx="http://www.springframework.org/schema/tx"
       xsi:schemaLocation="
        http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context.xsd
        http://www.springframework.org/schema/tx
        http://www.springframework.org/schema/tx/spring-tx.xsd">

    <context:component-scan base-package="fms" />

    <bean id="microFmsDataSource" class="org.apache.tomcat.jdbc.pool.DataSource" destroy-method="close">
        <property name="driverClassName" value="org.postgresql.Driver" />
        <property name="url" value="***" />
        <property name="username" value="***" />
        <property name="password" value="***" />

        <property name="testOnBorrow" value="true" />
        <property name="testOnReturn" value="true" />
        <property name="testWhileIdle" value="true" />
        <property name="validationQuery" value="select 1" />
        <property name="initialSize" value="5" />
        <property name="minIdle" value="10" />
        <property name="maxIdle" value="100" />
        <property name="maxActive" value="100" />
        <property name="removeAbandoned" value="true" />
    </bean>

    <bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
        <property name="dataSource" ref="microFmsDataSource"/>

        <property name="packagesToScan">
            <list>
                <value>fms</value>
            </list>
        </property>

        <property name="jpaVendorAdapter">
            <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter" />
        </property>

        <property name="jpaPropertyMap">
            <map>
                <entry key="hibernate.cache.provider_class" value="org.hibernate.cache.NoCacheProvider" />
                <entry key="hibernate.hbm2ddl.auto" value="validate" />
                <entry key="hibernate.dialect" value="org.hibernate.dialect.PostgreSQLDialect" />
                <entry key="hibernate.show_sql" value="true" />
                <entry key="hibernate.format_sql" value="true" />
                <entry key="hibernate.ejb.naming_strategy" value="org.hibernate.cfg.ImprovedNamingStrategy" />
            </map>
        </property>
    </bean>

    <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
        <property name="entityManagerFactory" ref="entityManagerFactory" />
    </bean>

    <tx:annotation-driven transaction-manager="transactionManager"/>
</beans>

柔性制造系统
升级后,我更改了NamingStrategy配置:

<entry key="hibernate.ejb.naming_strategy" value="org.hibernate.cfg.ImprovedNamingStrategy" />

像这样:

<entry key="hibernate.implicit_naming_strategy" value="***" />

并尝试了hibernate javadoc中列出的所有选项变体:

但是没有成功


您能否告诉我Hibernate 5中改进的命名策略的替代方案,并提供一个工作配置示例?

我想我找到了解决方案

为了实现我的目标,我使用了
hibernate.physical\u naming\u策略
配置,而不是
hibernate.implicit\u naming\u策略

我创建了一个
PhysicalNamingStrategy
接口的实现,该接口模拟了原始
ImprovedNamingStrategy
类的部分功能:

package fms.util.hibernate;

import org.apache.commons.lang.StringUtils;
import org.hibernate.boot.model.naming.Identifier;
import org.hibernate.boot.model.naming.PhysicalNamingStrategy;
import org.hibernate.engine.jdbc.env.spi.JdbcEnvironment;

public class ImprovedNamingStrategy implements PhysicalNamingStrategy {

    @Override
    public Identifier toPhysicalCatalogName(Identifier identifier, JdbcEnvironment jdbcEnv) {
        return convert(identifier);
    }

    @Override
    public Identifier toPhysicalColumnName(Identifier identifier, JdbcEnvironment jdbcEnv) {
        return convert(identifier);
    }

    @Override
    public Identifier toPhysicalSchemaName(Identifier identifier, JdbcEnvironment jdbcEnv) {
        return convert(identifier);
    }

    @Override
    public Identifier toPhysicalSequenceName(Identifier identifier, JdbcEnvironment jdbcEnv) {
        return convert(identifier);
    }

    @Override
    public Identifier toPhysicalTableName(Identifier identifier, JdbcEnvironment jdbcEnv) {
        return convert(identifier);
    }

    private Identifier convert(Identifier identifier) {
        if (identifier == null || StringUtils.isBlank(identifier.getText())) {
            return identifier;
        }

        String regex = "([a-z])([A-Z])";
        String replacement = "$1_$2";
        String newName = identifier.getText().replaceAll(regex, replacement).toLowerCase();
        return Identifier.toIdentifier(newName);
    }
}
创建此类后,我更改了以下配置:

<entry key="hibernate.ejb.naming_strategy" value="org.hibernate.cfg.ImprovedNamingStrategy" />
我希望此解决方案将对某人有所帮助。:)

这是我的工作,从


...
试试这个:

@Bean
public LocalSessionFactoryBean getSessionFactory() {
    LocalSessionFactoryBean localSessionFactoryBean = new LocalSessionFactoryBean();
    localSessionFactoryBean.setDataSource(getDataSource());
    localSessionFactoryBean.setHibernateProperties(getHibernateProperties());
    localSessionFactoryBean.setPackagesToScan(new String[]{"com.xxx.pojo"});
    // -----important-----
    localSessionFactoryBean.setPhysicalNamingStrategy(new CustomNamingStrategy());
    return localSessionFactoryBean;
}

public class CustomNamingStrategy extends PhysicalNamingStrategyStandardImpl {***

我也有同样的问题。我用spring boot的默认实现修复了它:

<property name="hibernate.implicit_naming_strategy" value="org.springframework.boot.orm.jpa.hibernate.SpringImplicitNamingStrategy" />
<property name="hibernate.physical_naming_strategy" value="org.springframework.boot.orm.jpa.hibernate.SpringPhysicalNamingStrategy" />

适用于寻找Java配置解决方案的任何人

hibernate 5.X中的
hibernate.ejb.naming\u策略属性似乎分为两部分:

hibernate.物理命名策略

hibernate.隐式命名策略

Spring为此提供了
SpringImplicitNamingStrategy
SpringPhysicalNamingStrategy

我的做法如下:

import javax.persistence.EntityManagerFactory;
import javax.sql.DataSource;

import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.orm.jpa.EntityManagerFactoryBuilder;
import org.springframework.boot.orm.jpa.hibernate.SpringImplicitNamingStrategy;
import org.springframework.boot.orm.jpa.hibernate.SpringPhysicalNamingStrategy;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.DependsOn;
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;

@Configuration
@DependsOn("myDataSource")
@EnableTransactionManagement
@EnableJpaRepositories(
        entityManagerFactoryRef = "myEntityManagerFactory",
        basePackages={"com.myapp.repo"},
        transactionManagerRef="myTransactionManager"
        )
public class MyJpaConfig {

    private Map<String, Object> properties;

    public MyJpaConfig() {
        properties = new HashMap<>();
        properties.put("hibernate.implicit_naming_strategy", SpringImplicitNamingStrategy.class.getName());
        properties.put("hibernate.physical_naming_strategy", SpringPhysicalNamingStrategy.class.getName());

    }

    @Bean(name = "myEntityManagerFactory")
    public LocalContainerEntityManagerFactoryBean entityManagerFactory(EntityManagerFactoryBuilder builder,
            @Qualifier("systemDataSource") DataSource dataSource) {
        LocalContainerEntityManagerFactoryBean build = builder.dataSource(dataSource)
                .packages("com.myapp.entity")
                .properties(properties)
                .build();
        return build;

    }

    @Bean(name = "myTransactionManager")
    public PlatformTransactionManager myTransactionManager(
            @Qualifier("myEntityManagerFactory") EntityManagerFactory myEntityManagerFactory) {
        return new JpaTransactionManager(myEntityManagerFactory);
    }
}
import javax.persistence.EntityManagerFactory;
导入javax.sql.DataSource;
导入org.springframework.beans.factory.annotation.Qualifier;
导入org.springframework.boot.orm.jpa.EntityManagerFactoryBuilder;
导入org.springframework.boot.orm.jpa.hibernate.SpringImplicitNamingStrategy;
导入org.springframework.boot.orm.jpa.hibernate.SpringPhysicalNamingStrategy;
导入org.springframework.context.annotation.Bean;
导入org.springframework.context.annotation.Configuration;
导入org.springframework.context.annotation.DependsOn;
导入org.springframework.data.jpa.repository.config.EnableJpaRepositories;
导入org.springframework.orm.jpa.JpaTransactionManager;
导入org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
导入org.springframework.transaction.PlatformTransactionManager;
导入org.springframework.transaction.annotation.EnableTransactionManagement;
@配置
@DependsOn(“myDataSource”)
@启用事务管理
@授权代理(
entityManagerFactoryRef=“myEntityManagerFactory”,
basePackages={“com.myapp.repo”},
transactionManagerRef=“myTransactionManager”
)
公共类MyJpaConfig{
私人地图财产;
公共MyJpaConfig(){
properties=newhashmap();
properties.put(“hibernate.implicit_naming_策略”,SpringImplicitNamingStrategy.class.getName());
properties.put(“hibernate.physical\u naming\u策略”,SpringPhysicalNamingStrategy.class.getName());
}
@Bean(name=“myEntityManagerFactory”)
公共LocalContainerEntityManagerFactoryBean entityManagerFactory(EntityManagerFactoryBuilder、,
@限定符(“systemDataSource”)数据源(数据源){
LocalContainerEntityManagerFactoryBean build=builder.dataSource(dataSource)
.packages(“com.myapp.entity”)
.物业(物业)
.build();
返回构建;
}
@Bean(name=“myTransactionManager”)
公共平台事务管理器myTransactionManager(
@限定符(“myEntityManagerFactory”)EntityManagerFactory(myEntityManagerFactory){
返回新的JpaTransactionManager(myEntityManagerFactory);
}
}

请找出我在研究命名策略时发现的以下三点:

  • 如果在实体类中提供
    @Table
    @Column
    注释,并且名称带有下划线,即用户id
    @Column(name=“user\u id”)
    ,则将列名称作为用户id;如果您将其命名为userid,那么如果您不使用任何策略或隐式策略(特别是
    org.hibernate.boot.model.naming.ImplicitNamingStrategyLegacyHbmImpl
    ),它将变为user\u id。因此,如果您想要一种策略,其中实体属性名称更改为带有下划线和小写字母的名称,即从userIduser\u id,则应使用隐式或无策略(实际上使用隐式策略)

  • 如果不希望命名策略在列名或类名中添加下划线,则需要使用的策略如下所示:
    spring.jpa.hibernate.naming.physical strategy=org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl
    。注释
    @表
    @列的
    名称属性中提供的内容将保持不变
    @Bean
    public LocalSessionFactoryBean getSessionFactory() {
        LocalSessionFactoryBean localSessionFactoryBean = new LocalSessionFactoryBean();
        localSessionFactoryBean.setDataSource(getDataSource());
        localSessionFactoryBean.setHibernateProperties(getHibernateProperties());
        localSessionFactoryBean.setPackagesToScan(new String[]{"com.xxx.pojo"});
        // -----important-----
        localSessionFactoryBean.setPhysicalNamingStrategy(new CustomNamingStrategy());
        return localSessionFactoryBean;
    }
    
    public class CustomNamingStrategy extends PhysicalNamingStrategyStandardImpl {***
    
    <property name="hibernate.implicit_naming_strategy" value="org.springframework.boot.orm.jpa.hibernate.SpringImplicitNamingStrategy" />
    <property name="hibernate.physical_naming_strategy" value="org.springframework.boot.orm.jpa.hibernate.SpringPhysicalNamingStrategy" />
    
    import javax.persistence.EntityManagerFactory;
    import javax.sql.DataSource;
    
    import org.springframework.beans.factory.annotation.Qualifier;
    import org.springframework.boot.orm.jpa.EntityManagerFactoryBuilder;
    import org.springframework.boot.orm.jpa.hibernate.SpringImplicitNamingStrategy;
    import org.springframework.boot.orm.jpa.hibernate.SpringPhysicalNamingStrategy;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.context.annotation.DependsOn;
    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;
    
    @Configuration
    @DependsOn("myDataSource")
    @EnableTransactionManagement
    @EnableJpaRepositories(
            entityManagerFactoryRef = "myEntityManagerFactory",
            basePackages={"com.myapp.repo"},
            transactionManagerRef="myTransactionManager"
            )
    public class MyJpaConfig {
    
        private Map<String, Object> properties;
    
        public MyJpaConfig() {
            properties = new HashMap<>();
            properties.put("hibernate.implicit_naming_strategy", SpringImplicitNamingStrategy.class.getName());
            properties.put("hibernate.physical_naming_strategy", SpringPhysicalNamingStrategy.class.getName());
    
        }
    
        @Bean(name = "myEntityManagerFactory")
        public LocalContainerEntityManagerFactoryBean entityManagerFactory(EntityManagerFactoryBuilder builder,
                @Qualifier("systemDataSource") DataSource dataSource) {
            LocalContainerEntityManagerFactoryBean build = builder.dataSource(dataSource)
                    .packages("com.myapp.entity")
                    .properties(properties)
                    .build();
            return build;
    
        }
    
        @Bean(name = "myTransactionManager")
        public PlatformTransactionManager myTransactionManager(
                @Qualifier("myEntityManagerFactory") EntityManagerFactory myEntityManagerFactory) {
            return new JpaTransactionManager(myEntityManagerFactory);
        }
    }