我有一种奇特的字段映射:
@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似乎没有任何会影响这一点的属性。
有谁知道有没有办法做到这一点?
发布于 2011-03-08 01:48:16
我不得不修补Hibernate来创建不同的外键名称,因为Hibernate为我创建的外键名称并不是很有用。
我获取了Hibernate源代码,并将类org.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-06 10:05:07
我也遇到了同样的问题,因为我找不到方法,最终只能查询数据库本身来获取该信息。
在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)、类型(如唯一约束)和列名。这应该足以返回一个有意义的错误消息。
我知道这不是很好,因为你失去了数据库的可移植性,但显然目前没有办法做到你所要求的……
https://stackoverflow.com/questions/4953412
复制相似问题