开发者

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 ge开发者_StackOverflow中文版neration time: org.hibernate.annotations.ForeignKey.

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


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.


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


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.


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

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜