【问题标题】:How to choose DDL Primary Key constraint names with JPA/Hibernate如何使用 JPA/Hibernate 选择 DDL 主键约束名称
【发布时间】:2011-03-18 09:02:30
【问题描述】:

存在一个专有的休眠注释来指定在 DDL 生成时使用的外键约束名称org.hibernate.annotations.ForeignKey

还有没有办法指定主键约束名称

【问题讨论】:

  • 其他 JPA 提供者可能允许它(例如那些也支持 JDO API(例如 DataNucleus),因为它是该 API 的标准),但不是 JPA API 的一部分(直到并包括JPA 2.2)

标签: java hibernate jpa orm


【解决方案1】:

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

这个功能请求实际上有一个很老的问题(HB-1245),但看起来并没有引起太多关注。

【讨论】:

  • 支持答案。对无法这样做的嘘声。
【解决方案2】:

您可以使用自定义方言中的一些小模块来控制生成的 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】:

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

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

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

    【讨论】:

    【解决方案4】:

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-06-16
      • 1970-01-01
      • 2015-11-16
      • 2012-07-15
      • 2021-11-20
      • 2019-04-29
      • 2016-08-14
      相关资源
      最近更新 更多