Martin Ždila
Martin Ždila

Reputation: 3219

Hibernate generates too long identifiers for Oracle

We are using JPA with Hibernate 4.3.8 and Oracle 11. Our entities doesn't have explicit DB identifier names declared in annotations and so we rely upon Hibernate to generate them correctly.

For MySQL it works properly but after we had switched to Oracle then we've encountered couple of the problems.

One of them is that Hibernate-generated schema contains identifiers longer than Oracle supports. We thought that Oracle10gDialect handles it but it seems we were wrong.

What is the best approach to add support of Oracle to our application? Must we explicitly declare all the database tables/columns/indexes... in annotations (@Table, @Column...)? Shouldn't it be Hibernate who takes a care of this dialect-specific task?

Another problem is that Hibernate also doesn't escape the keywords (eg. column name code must be escaped in Oracle). What if we decide to support another database in the future? Must we choose all the identifier names so that all of them suit for every DB? This seems to be very overhelming. (Note that the property hibernate.globally_quoted_identifiers can solve it partially but then @UniqueConstraint columns doesn't match.)

Or maybe... does Eclipselink handle this?

Upvotes: 3

Views: 2565

Answers (1)

przemek hertel
przemek hertel

Reputation: 4014

In such cases you can use Hibernate's NamingStrategy prepared for Oracle. In simple words: NamingStrategy tells Hibernate how to generate names for columns or tables.

You can provide oracle-aware NamingStrategy as I do for each of my Oracle/Hibernate projects.

Here is sample JPA configuration:

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

Here is the NamingStrategy I have been using for many projects:

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

look at smart abbreviating method that guarantees to produce Oracle-compliant name:

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

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

    return assembleResults(tokens);
}

There are many articles about applying NamingStratety with Hibernate, for example:

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

I hope this helps.

Upvotes: 5

Related Questions