I have a sort of exotic mapping for a field:
@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 is an entity and GradeLevel is an enum.
I am using Hibernate tools to generate the DDL for the schema. The schema that this generates is below:
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;
The problem is that I can't seem to change the constraint name for the foreign key between the collection table and the table for the entity used as the map key.
I've used @ForeignKey to specify constraint names for @OneToMany, @ManyToMany and other @ElementCollections with no problem. I've tried @ForiegnKey's "inverseName" attribute but it seems to be ignored. @MapKeyJoinColumn doesn't appear to have any properties that would affect this.
Does anyone know if there is a way to do this?
I had to patch Hibernate to create different foreign key names, because the ones Hibernate created for me weren't really useful.
I took the Hibernate source, and placed the Source of the class org.hibernate.mapping.Table
into my source folder, which is a the start of the classpath (the resulting jar in my project starts with a letter lower than the hibernate.jar, so this even works in webapps).
The I replaced the function uniqueColumnString with the following code (Original code at the top of the function):
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();
}
This returns automatically nice strings like "_Entity_attributeName_id", which will be used to create foreign keys like "fk_Entity_attributeName_id"! Never have to specify my names by hand again :)))
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With