unidirectional onetomany one many elementcollection ejemplo java hibernate hibernate-annotations

java - onetomany - hibernate one to one



Especifique el nombre de la restricción de clave externa al usar Map y @ElementCollection con Hibernate (2)

Tuve el mismo problema y, como no podía encontrar la manera de hacerlo, terminé consultando la base de datos para obtener esa información.

Ejecutando esta consulta en el SERVIDOR SQL

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

Obtendrá nombre de tabla, nombre de restricción (como FK1BCA4A883A97C498), tipo (como restricción UNIQUE) y nombre de columna. Eso debería ser suficiente para devolver un mensaje de error significativo.

Sé que no es genial porque pierdes la portabilidad de db pero aparentemente no hay forma de hacer lo que estás pidiendo en este momento ...

Tengo una especie de mapeo exótico para un campo:

@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 es una entidad y GradeLevel es una enumeración.

Estoy usando las herramientas de Hibernate para generar el DDL para el esquema. El esquema que esto genera está abajo:

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;

El problema es que parece que no puedo cambiar el nombre de la restricción para la clave externa entre la tabla de recopilación y la tabla para la entidad utilizada como la clave del mapa.

He usado @ForeignKey para especificar nombres de restricciones para @OneToMany, @ManyToMany y otras @ElementCollections sin ningún problema. He intentado el atributo "inverseName" de @ ForiegnKey pero parece ser ignorado. Parece que @MapKeyJoinColumn no tiene ninguna propiedad que pueda afectar esto.

¿Alguien sabe si hay una manera de hacer esto?


Tuve que parchear Hibernate para crear diferentes nombres de clave externa, porque los que Hibernate creó para mí no eran realmente útiles.

Tomé el origen de Hibernate y coloqué el Origen de la clase org.hibernate.mapping.Table en mi carpeta de origen, que es el comienzo del classpath (el archivo jar resultante en mi proyecto comienza con una letra más baja que hibernate.jar , así que esto incluso funciona en webapps).

Reemplacé la función uniqueColumnString con el siguiente código (código original en la parte superior de la función):

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

Esto devuelve cadenas agradables automáticamente como "_Entity_attributeName_id", que se utilizará para crear claves externas como "fk_Entity_attributeName_id"! Nunca más tengo que especificar mis nombres a mano :)))