首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >在Hibernate中使用Map和@ElementCollection时指定外键约束名称

在Hibernate中使用Map和@ElementCollection时指定外键约束名称
EN

Stack Overflow用户
提问于 2011-02-10 12:33:39
回答 2查看 5.9K关注 0票数 19

我有一种奇特的字段映射:

代码语言:javascript
复制
@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。此操作生成的模式如下:

代码语言:javascript
复制
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似乎没有任何会影响这一点的属性。

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

EN

回答 2

Stack Overflow用户

发布于 2011-03-08 01:48:16

我不得不修补Hibernate来创建不同的外键名称,因为Hibernate为我创建的外键名称并不是很有用。

我获取了Hibernate源代码,并将类org.hibernate.mapping.Table的源代码放到了我的源文件夹中,这个文件夹是类路径的开头(在我的项目中得到的jar以一个比hibernate.jar更低的字母开头,所以这在webapps中也是有效的)。

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

代码语言:javascript
复制
    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”这样的外键!再也不用手动指定我的名字了:))

票数 6
EN

Stack Overflow用户

发布于 2011-03-06 10:05:07

我也遇到了同样的问题,因为我找不到方法,最终只能查询数据库本身来获取该信息。

在SQL SERVER上运行此查询

代码语言:javascript
复制
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)、类型(如唯一约束)和列名。这应该足以返回一个有意义的错误消息。

我知道这不是很好,因为你失去了数据库的可移植性,但显然目前没有办法做到你所要求的……

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/4953412

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档