2009-07-20 32 views
13

tengo estas dos clases (tabla)¿Puede agregar campos adicionales a la tabla extra de @ManyToMany Hibernate?

@Entity 
@Table(name = "course") 
public class Course { 

    @Id 
    @Column(name = "courseid") 
    private String courseId; 
    @Column(name = "coursename") 
    private String courseName; 
    @Column(name = "vahed") 
    private int vahed; 
    @Column(name = "coursedep") 
    private int dep; 
    @ManyToMany(fetch = FetchType.LAZY) 
    @JoinTable(name = "student_course", joinColumns = @JoinColumn(name = "course_id"), inverseJoinColumns = @JoinColumn(name = "student_id")) 
    private Set<Student> student = new HashSet<Student>(); 
//Some setter and getter 

y éste:

@Entity 
    @Table(name = "student") 
    public class Student { 

     @Id 
     @Column(name="studid") 
     private String stId; 
     @Column(nullable = false, name="studname") 
     private String studName; 
     @Column(name="stmajor") 
     private String stMajor; 
     @Column(name="stlevel", length=3) 
     private String stLevel; 
     @Column(name="stdep") 
     private int stdep; 

     @ManyToMany(fetch = FetchType.LAZY) 
     @JoinTable(name = "student_course" 
       ,joinColumns = @JoinColumn(name = "student_id") 
       ,inverseJoinColumns = @JoinColumn(name = "course_id") 
     ) 
     private Set<Course> course = new HashSet<Course>(); 
//Some setter and getter 

Después de ejecutar este código de una mesa adicional fue creado en la base de datos (student_course), ahora yo quiero saber cómo puedo añadir campo extra en esta tabla como (grado, la fecha, y ... (me refiero a la mesa student_course)) veo alguna solución, pero que no me gustan ellos, también tengo algún problema con ellos:

First Sample

+0

Puede agregar una columna adicional usando \ @OrderColumn que es una columna int utilizada para almacenar el orden de una relación many2many. Desearía que agreguen un \ @TempolalColumns para agregar los campos fromDate y toDate también –

Respuesta

16

Si agrega campos adicionales en una tabla vinculada (STUDENT_COURSE), debe elegir un enfoque de acuerdo con la respuesta de skaffman u otro como se muestra a continuación.

Hay un enfoque en el que la tabla vinculada (STUDENT_COURSE) se comporta como un @Embeddable acuerdo con:

@Embeddable 
public class JoinedStudentCourse { 

    // Lets suppose you have added this field 
    @Column(updatable=false) 
    private Date joinedDate; 

    @ManyToOne(fetch=FetchType.LAZY) 
    @JoinColumn(name="STUDENT_ID", insertable=false, updatable=false) 
    private Student student; 

    @ManyToOne(fetch=FetchType.LAZY) 
    @JoinColumn(name="COURSE_ID", insertable=false, updatable=false) 
    private Course course; 

    // getter's and setter's 

    public boolean equals(Object instance) { 
     if(instance == null) 
      return false; 

     if(!(instance instanceof JoinedStudentCourse)) 
      return false; 

     JoinedStudentCourse other = (JoinedStudentCourse) instance; 
     if(!(student.getId().equals(other.getStudent().getId())) 
      return false; 

     if(!(course.getId().equals(other.getCourse().getId())) 
      return false; 

     // ATT: use immutable fields like joinedDate in equals() implementation 
     if(!(joinedDate.equals(other.getJoinedDate())) 
      return false; 

     return true; 
    } 

    public int hashcode() { 
     // hashcode implementation 
    } 

} 

Por lo que tendrá en ambas clases del estudiante y Curso

public class Student { 

    @CollectionOfElements 
    @JoinTable(
     [email protected](name="STUDENT_COURSE"), 
     [email protected](name="STUDENT_ID") 
    ) 
    private Set<JoinedStudentCourse> joined = new HashSet<JoinedStudentCourse>(); 

} 

public class Course { 

    @CollectionOfElements 
    @JoinTable(
     [email protected](name="STUDENT_COURSE"), 
     [email protected](name="COURSE_ID") 
    ) 
    private Set<JoinedStudentCourse> joined = new HashSet<JoinedStudentCourse>(); 

} 

recordar: @ La clase incrustable tiene su ciclo de vida vinculado a la clase de entidad propietaria (tanto Estudiante como Curso), así que ocúpese de eso.

consejos: el equipo de Hibernate apoya estos dos enfoques (@OneToMany (respuesta de skaffman) o @CollectionsOfElements) debido a algunas limitaciones en el mapeo @ManyToMany - operación en cascada.

cordiales,

+0

gran respuesta.si solo se necesita una columna de índice para mapear a una Lista, se puede agregar @OrderColumn a – cproinger

+2

Cuando intenté la solución anterior, recibí el error 'Columna repetida en la asignación para la recopilación '. Alguna idea ? –

+0

Recibo el mismo error que Ankur Raiyani, mi solución es la de skaffman. usando la identificación incorporada dentro del curso de estudiante para asegurarme de que tengo la clave primaria correcta para mí. Y luego quité la clave incrustada y arrojé un @Id para cada relación de manToOne –

7

La tabla student_course está allí simplemente para registrar la asociación entre las dos entidades. Es administrado por hibernación y no puede contener otros datos.

El tipo de datos que desea registrar debe modelarse como otra entidad. Tal vez podría asociarse uno a varios entre Course y StudentResult (que contiene la calificación, etc.), y luego una asociación muchos a uno entre StdentResult y Student.

+0

Tanx man Lo considero – Am1rr3zA

3

Elimine el muchos-a-muchos, cree una clase llamada StudentCourseRelationship y configure uno para manys en Student y Course para StudentCourseRelationship.

Usted puede poner todo tipo de cosas en él, como DateEnrolled, DateKickedOut etc etc

OMI el mapeo muchos-a-muchos es un poco de aire acondicionado.

+0

Tanx man Lo considero – Am1rr3zA

+1

¿Qué tal DateGotToGripsWithAssociations? :) – skaffman

Cuestiones relacionadas