Hibernate为Oracle生成太长的标识符

时间:2015-06-01 15:56:03

标签: oracle hibernate

我们正在将JPA与Hibernate 4.3.8和Oracle 11一起使用。我们的实体没有在注释中声明的显式DB标识符名称,所以我们依赖Hibernate来正确生成它们。

对于MySQL它可以正常工作,但在我们切换到Oracle后,我们遇到了一些问题。

其中之一是Hibernate生成的模式包含的标识符比Oracle支持的标识符更长。我们认为Oracle10gDialect处理它但看起来我们错了。

在我们的应用程序中添加Oracle支持的最佳方法是什么?我们是否必须在注释(@Table@Column ...)中显式声明所有数据库表/列/索引...?难道不是Hibernate会照顾这种特定于方言的任务吗?

另一个问题是Hibernate也没有转义关键字(例如,列名code必须在Oracle中转义)。如果我们决定将来支持另一个数据库怎么办?我们必须选择所有标识符名称,以便所有标识符都适合每个数据库吗?这似乎非常难以理解。 (请注意,属性hibernate.globally_quoted_identifiers可以部分解决,但@UniqueConstraint列不匹配。)

或许...... Eclipselink会处理这个吗?

1 个答案:

答案 0 :(得分:4)

在这种情况下,您可以使用为Oracle准备的Hibernate的 NamingStrategy 。 简单来说:NamingStrategy告诉Hibernate如何为列或表生成名称

您可以为我的每个Oracle / Hibernate项目提供 oracle-aware NamingStrategy

以下是JPA配置示例:

<bean id="entityManagerFactory"
  class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"
  ...

<property name="jpaPropertyMap">
 <map>
  <entry key="hibernate.ejb.naming_strategy" value="com.mycompany.OracleNamingStrategy"/>
  <entry key="hibernate.dialect"         value="org.hibernate.dialect.Oracle10gDialect"/>
    ...
 </map>
</property>
</bean>

以下是我在许多项目中使用的NamingStrategy:

https://code.google.com/p/hibernate-naming-strategy-for-oracle/source/browse/trunk/src/de/schauderhaft/hibernate/OracleNamingStrategy.java

查看智能缩写方法,确保生成符合Oracle标准的名称:

public static String abbreviateName(String someName) {
    if (someName.length() <= MAX_LENGTH)
        return someName;

    String[] tokens = splitName(someName);
    shortenName(someName, tokens);

    return assembleResults(tokens);
}

有很多关于将NamingStratety应用于Hibernate的文章,例如:

1。 http://www.petrikainulainen.net/programming/tips-and-tricks/implementing-a-custom-namingstrategy-with-hibernate/

2。 http://sudhirmongia.blogspot.com/2010/08/naming-strategy-in-hibernate.html

我希望这会有所帮助。