2009-07-20 13 views
13

Je ces deux classes (tableau)Peut-on ajouter des champs supplémentaires à la table supplémentaire Hibernate de @ManyToMany?

@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 

et celui-ci:

@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 

Après avoir exécuté ce code une table supplémentaire a été créé dans la base de données (student_course), maintenant je veux savoir comment puis-je ajouter le champ supplémentaire dans ce tableau comme (grade, la date et ... (je veux dire la table student_course)) Je vois une solution mais je ne les aime pas, j'ai aussi un problème avec eux:

First Sample

+0

Vous pouvez ajouter une colonne supplémentaire en utilisant \ @OrderColumn qui est une colonne int utilisée pour stocker l'ordre de tri d'une relation many2many. Je souhaite qu'ils ajouteraient un \ @TempolalColumns pour ajouter un champs fromDate et toDate aussi –

Répondre

16

Si vous ajoutez des champs supplémentaires sur une table liée (STUDENT_COURSE), vous devez choisir une approche en fonction de la réponse de skaffman ou d'une autre comme indiqué ci-dessous.

Il y a une approche où la table liée (STUDENT_COURSE) se comporte comme un @Embeddable selon:

@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 
    } 

} 

Vous aurez dans les deux classes d'étudiants et des cours

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

} 

rappeler: @ La classe Embeddable a son cycle de vie lié à la classe d'entité propriétaire (Student et Course), alors prenez soin d'elle. Conseil: l'équipe d'Hibernate supporte ces deux approches (@OneToMany (réponse de Skaffman) ou @CollectionsOfElements) en raison de certaines limitations dans le mappage @ManyToMany - opération en cascade.

salutations,

+0

bonne réponse.Si l'on n'a besoin que d'une colonne d'index pour le mappage vers une liste, on peut simplement ajouter @OrderColumn si – cproinger

+2

Lorsque j'ai essayé la solution ci-dessus, j'ai obtenu l'erreur 'Colonne répétée dans la cartographie pour la collection'. Une idée ? –

+0

Je reçois la même erreur que Ankur Raiyani, ma solution est celle du skaffman. en utilisant id intégré dans le studentcourse pour s'assurer que j'ai la bonne clé primaire passe pour moi. Et puis j'ai enlevé la clé intégrée et ai jeté un @Id pour chaque relation manToOne –

7

La table student_course est là uniquement pour enregistrer l'association entre les deux entités. Il est géré par hibernate et ne peut contenir aucune autre donnée.

Le type de données que vous souhaitez enregistrer doit être modélisé en tant qu'autre entité. Peut-être que vous pourriez une association un-à-plusieurs entre Course et StudentResult (qui contient le grade, etc), puis une association plusieurs-à-un entre StdentResult et Student.

+0

Tanx man Je le considère – Am1rr3zA

3

Supprimez le plusieurs-à-plusieurs, créez une classe appelée StudentCourseRelationship et configurez one to manys sur Student et Course to StudentCourseRelationship.

Vous pouvez mettre toutes sortes de choses sur elle, comme DateEnrolled, DateKickedOut etc., etc.

OMI nombreux à plusieurs cartographie est un peu con.

+0

Tanx man Je le considère – Am1rr3zA

+1

Que diriez-vous de DateGotToGripsWithAssociations? :) – skaffman

Questions connexes