具有Hibernate

时间:2018-03-05 20:26:32

标签: oracle hibernate identifier maxlength

最近将数据库迁移到Oracle,由于标识符的最大长度为30,因此必须缩短一些列名。

此应用程序已在少数环境中投入生产,因此在任何地方缩短列名称只能作为最后的手段。

我考虑过实现PhysicalNamingStrategy和LogicalNamingStrategy,但是它不起作用,因为我无法从缩短的物理名称中解析逻辑名称。

我怀疑我可以为这些情况创建一个基本实体,并将其扩展为仅覆盖列名。但这会迫使我明确列出要在persistence.xml中使用的实体类。

任何人都有更好的建议吗?

1 个答案:

答案 0 :(得分:0)

我扩展了PhysicalNamingStrategyStandardImpl并覆盖了 toPhysicalColumnName 方法,因为我们遇到的唯一问题是Oracle的某些列名太长了。如果标识符更长并且数据库是Oracle,则此代码将字符串截断为30个字符。

package my.package;

import org.hibernate.boot.model.naming.Identifier;
import org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl;
import org.hibernate.engine.jdbc.env.spi.JdbcEnvironment;

public class CustomNamingStrategy extends PhysicalNamingStrategyStandardImpl {

    private static final long serialVersionUID = 1L;

    @Override
    public Identifier toPhysicalColumnName(Identifier identifier, JdbcEnvironment jdbcEnv) {
        if (jdbcEnv.getDialect().toString().indexOf("Oracle") > -1 && identifier.getText().length() > 30) {
            return Identifier.toIdentifier(identifier.getText().substring(0, 30));
        } else {
            return identifier;
        }
    }
}

请注意,我的每个实体字段都已使用@Column注释进行注释,其中指定了物理名称。您可以在下面看到必须为Oracle截断的列名:

@Column(name = "MARKER_DISTANCE_START_POINT_CHAR")
public String getMarkerDistanceStartPointChar() {
    return this.markerDistanceStartPointChar;
}

public void setMarkerDistanceStartPointChar(String markerDistanceStartPointChar) {
    this.markerDistanceStartPointChar = markerDistanceStartPointChar;
}

然后我需要调整我的hibernate配置来注册我的自定义命名策略。使用JPA执行此操作,您在 persistence.xml 中添加以下 hibernate.physical_naming_strategy 属性。

<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd" version="1.0">
    <persistence-unit name="pu_name">
        <jta-data-source>java:comp/env/jndyName</jta-data-source>
        <properties>
            <property name="hibernate.show_sql" value="true" />
            <property name="hibernate.format_sql" value="true" />
            <property name="hibernate.physical_naming_strategy" value="my.package.CustomNamingStrategy"/>
        </properties>
    </persistence-unit>
</persistence>

这不是性感,但它解决了它。希望这个解决方案可以帮助其他人。