19

我对一个字段有一种奇异的映射:

@ElementCollection
@CollectionTable(name = "studentGradeLevel", joinColumns = @JoinColumn(name = "studentId"))
@MapKeyJoinColumn(name = "schoolYearId")
@Column(name = "gradeLevel", nullable = false)
@ForeignKey(name = "fkStudentGrade2Student")
private Map<SchoolYear, GradeLevel> gradeLevels;

SchoolYear 是一个实体, GradeLevel 是一个枚举。

我正在使用 Hibernate 工具为模式生成 DDL。这生成的架构如下:

create table studentGradeLevel (
    studentId numeric(19,0) not null,
    gradeLevel int not null,
    schoolYearId int not null,
    primary key (studentId, schoolYearId)
);

alter table studentGradeLevel 
    add constraint FK1BCA4A883A97C498 
    foreign key (schoolYearId) 
    references schoolYear;

alter table studentGradeLevel 
    add constraint fkStudentGrade2Student 
    foreign key (studentId) 
    references student;

问题是我似乎无法更改集合表和用作映射键的实体表之间的外键的约束名称。

我已经使用@ForeignKey 为@OneToMany、@ManyToMany 和其他@ElementCollections 指定约束名称,没有问题。我已经尝试过@ForiegnKey 的“inverseName”属性,但它似乎被忽略了。@MapKeyJoinColumn 似乎没有任何会影响这一点的属性。

有谁知道是否有办法做到这一点?

4

2 回答 2

6

我不得不修补 Hibernate 以创建不同的外键名称,因为 Hibernate 为我创建的那些并不是真正有用的。

我获取了 Hibernate 源,并将类的 Sourceorg.hibernate.mapping.Table放入我的源文件夹中,这是类路径的开始(我项目中生成的 jar 以低于 hibernate.jar 的字母开头,所以这甚至适用于 webapps )。

我将函数 uniqueColumnString 替换为以下代码(函数顶部的原始代码):

    public String uniqueColumnString(Iterator iterator, String referencedEntityName) {
//        int result = 0;
//        if ( referencedEntityName != null ) {
//            result += referencedEntityName.hashCode();
//        }
//        while ( iterator.hasNext() ) {
//            result += iterator.next().hashCode();
//        }
//        return ( Integer.toHexString( name.hashCode() ) + Integer.toHexString( result ) ).toUpperCase();
          StringBuilder retVal = new StringBuilder();
          retVal.append("_").append(referencedEntityName);
          while( iterator.hasNext() ) {
              Column c = (Column)iterator.next();
              retVal.append("_");
              retVal.append(c.getName());
          }
          return retVal.toString();
    }

这会自动返回像“_Entity_attributeName_id”这样的好字符串,它将用于创建像“fk_Entity_attributeName_id”这样的外键!再也不用手动指定我的名字了:)))

于 2011-03-07T17:48:15.683 回答
0

我遇到了同样的问题,因为我找不到解决方法,所以最终查询数据库本身以获取该信息。

在 SQL SERVER 上运行此查询

select kcu.TABLE_NAME, kcu.CONSTRAINT_NAME, tc.CONSTRAINT_TYPE, kcu.COLUMN_NAME
from INFORMATION_SCHEMA.TABLE_CONSTRAINTS as tc
join INFORMATION_SCHEMA.KEY_COLUMN_USAGE as kcu
on kcu.CONSTRAINT_SCHEMA = tc.CONSTRAINT_SCHEMA
and kcu.CONSTRAINT_NAME  = tc.CONSTRAINT_NAME
and kcu.TABLE_SCHEMA    = tc.TABLE_SCHEMA
and kcu.TABLE_NAME = tc.TABLE_NAME

您将获得表名、约束名称(如 FK1BCA4A883A97C498)、类型(如 UNIQUE 约束)和列名。这应该足以返回有意义的错误消息。

我知道这不是很好,因为您失去了数据库的可移植性,但显然目前没有办法满足您的要求......

于 2011-03-06T02:05:07.490 回答