Tengo una situación bastante única al tratar de asignar una sola tabla a varias entidades en JPA. He leído sobre @Embeddable y @ElementCollection, pero no estoy seguro de cómo usarlos en mi situación (o si puedo). La tabla de una base de datos contiene información del curso. Puede haber filas en la tabla donde todo en el curso sea el mismo excepto por algunos valores, como el número de habitación y el día. Por ejemplo:Asignación de una sola tabla a la colección incrustable en JPA
TERM_CODE SUBJECT_CODE ROOM DAY INSTRUCTOR_ID
201220 EGRE 0101 TR 123
201220 EGRE 0103 W 124
¿Hay alguna manera de que pueda extraer datos de dos filas que el anterior, y poner los datos comunes en un objeto y los diferentes valores en una colección de objetos separados? Aquí está un ejemplo de cómo me gustaría tener las clases definidas:
@Entity
public class Course implements Serializable {
@Id
@Column(name = "TERM_CODE")
private Long termCode;
@Column(name = "SUBJECT_CODE")
private String subjectCode;
@Embedded
Collection<CourseSchedule> schedule;
public Long getTermCode() {
return termCode;
}
public void setTermCode(Long termCode) {
this.termCode = termCode;
}
public String getSubjectCode() {
return subjectCode;
}
public void setSubjectCode(String subjectCode) {
this.subjectCode = subjectCode;
}
}
CourseSchedule:
@Embeddable
public class CourseSchedule {
private String room;
private String day;
public String getRoom() {
return room;
}
public void setRoom(String room) {
this.room = room;
}
public String getDay() {
return day;
}
public void setDay(String day) {
this.day = day;
}
public String getInstructorId() {
return instructorId;
}
public void setInstructorId(String instructorId) {
this.instructorId = instructorId;
}
}
también estoy confundido en cuanto a lo que mi JPQL se vería en esta situación una vez que los consigo mapeado.
EDIT:
Si añado @Id a la columna de TERM_CODE, un objeto del curso se devuelve sin errores Hibernate, pero la colección CourseSchedule que forma parte del curso es nula.
EDIT 2:
he tratado de jugar con el tratamiento de golf y CourseSchedule como dos tablas separadas (aunque no lo son), pero me parece que no puede conseguir que unen utilizando @OneToMany y @ManyToOne.
@Entity
@IdClass(CourseId.class)
@Table(name = "course_table")
public class Course implements Serializable {
@OneToMany(mappedBy = "course")
private Collection<CourseSchedule> schedule;
@Id
@Column(name = "TERM_CODE")
private Long termCode;
@Id
@Column(name = "SUBJECT_CODE")
private Long subjectCode;
...
}
@Entity
@IdClass(CourseScheduleId.class)
@Table(name = "course_table")
public class CourseSchedule implements Serializable {
@ManyToOne
@JoinColumns({
@JoinColumn(name="TERM_CODE", referencedColumnName="TERM_CODE"),
@JoinColumn(name = "SUBJECT_CODE", referencedColumnName="SUBJECT_CODE")
})
private Course course;
@Column(name = "TERM_CODE")
private Long termCode;
@Column(name = "SUBJECT_CODE")
private Long subjectCode;
@Id
private String room;
@Id
private String day;
@Id
@Column(name = "INSTRUCTOR_ID")
private String instructorId;
...
}
(El CourseId
y CourseScheduleId
son clases simples que se usan para el ID compuesto.) El mapeo por encima de devolver el siguiente error:
org.hibernate.MappingException: Foreign key (FK82D03688F590EF27:course_table [TERM_CODE,SUBJECT_CODE])) must have same number of columns as the referenced primary key (course_table [ROOM,DAY,INSTRUCTOR_ID)
No necesito el CourseSchedule refiriéndose de nuevo al curso si eso ayuda a que sea más fácil.
¿Alguna idea? Mi único otro pensamiento es definirlos como entidades completamente separadas (no unidas), y luego de alguna manera mapearlas usando JPQL.
Supongo que este es un DB existente? por lo que no puede usar una clave externa al TERM_CODE en una tabla de CourseSchedule? Es posible que tenga una buena razón para hacer esto, pero duplicar algunos datos solo para almacenar la información de ROOM y DAY. ¿Qué informa hibernate cuando lo mapea así? – bvanvelsen
Lamentablemente no puedo cambiar la base de datos, y todo está en una tabla. Ojalá pudiera convencerlos de normalizarlo, pero eso no está sucediendo. – acvcu
Si lo ejecuto en su forma actual, aparece el error "No se ha especificado ningún identificador para entidad: Curso", que casi debería haber esperado. Otro problema es que la tabla de la base de datos no define una clave principal. – acvcu