Jan
Jan

Reputation: 9697

How to choose DDL Primary Key constraint names with JPA/Hibernate

There exists a proprietary hibernate annotation to specify the Foreign Key constraint names that are used at DDL generation time: org.hibernate.annotations.ForeignKey.

Is there also a way to specify the Primary Key constraint names?

Upvotes: 19

Views: 11959

Answers (4)

Lance
Lance

Reputation: 762

You can control the generated PK constraint names with a few small mods in a custom dialect. For example, here's how to do it in Oracle (the same approach works for SQLServer & DB2):

public class CustomOracleDialect extends org.hibernate.dialect.Oracle10gDialect {

   private CustomTableExporter customTableExporter;

   public CustomOracleDialect () {
     super();
     customTableExporter = new CustomTableExporter(this);
   }

   @Override
   public Exporter<Table> getTableExporter () {
     return customTableExporter;
   }

   static class CustomTableExporter extends StandardTableExporter {
     private final static int MAX_TABLE_NAME_LENGTH = 30;

     public CustomTableExporter (Dialect dialect) {
        super(dialect);
     }

     @Override
     public String[] getSqlCreateStrings (Table table, Metadata metadata) {
        final String[] sqlCreateStrings = super.getSqlCreateStrings(table, metadata);

        //-- replace " primary key" with " constraint TABLE_NAME_PK primary key "

        final String namedPkConstraint = " constraint " + StringUtils.truncate(table.getName(), MAX_TABLE_NAME_LENGTH - 3) + "_PK primary key ";

        for (int i = 0; i < sqlCreateStrings.length; ++i) {
           sqlCreateStrings[i] = StringUtils.replace(sqlCreateStrings[i], " primary key ", namedPkConstraint);
        }

        return sqlCreateStrings;
     }
   }
}

This will change the generated DDL from this:

-- BEFORE: 
create table FOO_ENTITY (
  FOO_ENTITY_ID number(19, 0)      not null,
  JOB_NAME      varchar2(128 char) not null,
  primary key (FOO_ENTITY_ID)
);

To this :

-- AFTER: 
create table FOO_ENTITY (
  FOO_ENTITY_ID number(19, 0)      not null,
  JOB_NAME      varchar2(128 char) not null,
  constraint FOO_ENTITY_PK primary key (FOO_ENTITY_ID)
);

Upvotes: 6

arkauss
arkauss

Reputation: 21

The class org.hibernate.mapping.PrimaryKey does the following:

public String sqlConstraintString(Dialect dialect) {
    StringBuilder buf = new StringBuilder("primary key (");
    Iterator iter = getColumnIterator();
    while ( iter.hasNext() ) {
        buf.append( ( (Column) iter.next() ).getQuotedName(dialect) );
        if ( iter.hasNext() ) {
            buf.append(", ");
        }
    }
    return buf.append(')').toString();
}

The solution would be to override this method and return a string starting with "constraint YOUR_CONSTRAINT_NAME primary key" to make it possible. Unfortunately there's no way of overriding this.

Upvotes: 2

Pascal Thivent
Pascal Thivent

Reputation: 570585

Not possible with standard JPA and not supported by Hibernate for Primary Key constraints neither.

There is actually a very old issue about this feature request (HB-1245) but it looks like it doesn't get much attention.

Upvotes: 17

Marco
Marco

Reputation: 9095

If you're talking about choosing the name of your primary key (in the database), Hibernate can not do that.

Remember, Hibernate is a framework that is primarly focused on mapping objects, not on the creation/maintenance of database entities.

With regards to defining the primary key, the following link (particularly 2.2.3.2) might be helpful: Mapping identifier properties in the JBoss Hibernate guide

Upvotes: 0

Related Questions