如何使用JPA / Hibernate选择DDL主键约束名称

时间:2010-07-20 10:40:15

标签: java hibernate jpa orm

存在专有的hibernate注释,用于指定在DDL生成时使用的外键约束 名称 org.hibernate.annotations.ForeignKey

是否还有一种方法可以指定主键约束 名称

4 个答案:

答案 0 :(得分:8)

标准JPA不可能,Hibernate也不支持主键约束。

关于此功能请求(HB-1245)实际上存在一个非常古老的问题,但它看起来并没有得到太多关注。

答案 1 :(得分:1)

如果您正在谈论选择主键的名称(在数据库中),Hibernate可以这样做。

请记住,Hibernate是一个主要关注映射对象的框架,而不是数据库实体的创建/维护。

关于定义主键,以下链接(特别是2.2.3.2)可能会有所帮助:Mapping identifier properties in the JBoss Hibernate guide

答案 2 :(得分:1)

您可以使用自定义方言中的几个小mod来控制生成的PK约束名称。例如,以下是在Oracle中进行操作的方法(对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;
     }
   }
}

这将从此处更改生成的DDL:

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

对此:

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

答案 3 :(得分:0)

org.hibernate.mapping.PrimaryKey类执行以下操作:

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

解决方案是重写此方法,并返回以“ constraint YOUR_CONSTRAINT_NAME主键”开头的字符串,以使其成为可能。不幸的是,没有办法覆盖它。