spring - hibernate 5命名策略配置 [英] spring - hibernate 5 naming strategy configuration

查看:2905
本文介绍了spring - hibernate 5命名策略配置的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I am writing application using postgresql database and spring + hibernate frameworks.

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

I upgraded spring framework from 4.1.5.RELEASE to 4.2.0.RELEASE version and upgraded hibernate framework from 4.3.7.Final to 5.0.0.Final version.

升级后,我遇到了NamingStrategy的问题。在postgresql数据库中,表列名以小写字母分隔,以下划线分隔,在应用程序层中,bean属性位于camelcase中。

After upgrade I have problems with NamingStrategy. In postgresql database, table column names are in lowercase separated by underscore, in application layer, bean properties are in camelcase.

这是旧版本的配置文件: / p>

This is working spring configuration file for older version:

<?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配置:

After upgrade I changed NamingStrategy configuration:

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

如下:

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

并尝试了hibernate javadoc中列出的所有选项: https://docs.jboss.org/hibernate/orm/5.0/javadocs/org/hibernate/cfg/ AvailableSettings.html#IMPLICIT_NAMING_STRATEGY

and tried all variants of options listed in hibernate javadoc: https://docs.jboss.org/hibernate/orm/5.0/javadocs/org/hibernate/cfg/AvailableSettings.html#IMPLICIT_NAMING_STRATEGY

但未成功。

你能告诉我什么是

推荐答案

我认为我找到了解决方案。

I think I found the solution.

为了实现我的目标,我使用了 hibernate.physical_naming_strategy 配置,而不是 hibernate.implicit_naming_strategy

To achieve my goal, I used hibernate.physical_naming_strategy configuration, instead of hibernate.implicit_naming_strategy.

我创建了一个 PhysicalNamingStrategy 接口的实现,它模拟了原始 ImprovedNamingStrategy class:

I created an implementation of the PhysicalNamingStrategy interface which simulates part of the functionality of the original ImprovedNamingStrategy class:

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" />

<entry key="hibernate.physical_naming_strategy" value="fms.util.hibernate.ImprovedNamingStrategy" />

现在一切正常。

此解决方案仅涵盖 ImprovedNamingStrategy 的一小部分。在我的项目中,对于表映射和连接映射,我始终明确地指定表或连接列的名称。我依靠隐式名称转换只为列名。所以这个简单的解决方案对我来说是可以接受的。

This solution covers only small part of ImprovedNamingStrategy. In my project, for table mapping and join mapping, I always specify the name of table or join column explicitly. I rely on implicit name conversion only for column names. So this simple solution was acceptable for me.

这是我的Spring配置文件的完整示例:

This is a full example of my Spring configuration file:

<?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.physical_naming_strategy" value="fms.util.hibernate.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>

我希望这个解决方案对某人有帮助。 :)

I hope this solution will be helpful for somebody. :)

这篇关于spring - hibernate 5命名策略配置的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆