2011-12-20 36 views
10

我有一個在EJB中設計ManyToMany的問題,一個連接表怎麼可以有一個屬性?
下面是一個例子,學生和課程是ManyToMany,每個學生都有很多課程,許多學生選擇一門課程。JPA ManyToMany,JoinTable如何擁有一個屬性?

@Entity 
    public class Student implements Serializable { 
     @Id 
     @GeneratedValue(strategy = GenerationType.AUTO) 
     Long id; 
     String name; 
     private Collection<Course> courses; 

     @ManyToMany(mappedBy = "students",cascade=CascadeType.ALL)  
     public Collection<Course> getCourses() { 
      return this.courses; 
     } 

     public void setCourses(Collection<Course> courses) { 
      this.courses = courses; 
     } 

    } 


    @Entity 
    public class Course implements Serializable { 
     @Id 
     @GeneratedValue(strategy = GenerationType.AUTO) 
     Long id; 
     String name; 
     private Collection<Student> students; 

     @ManyToMany(cascade=CascadeType.ALL) 
     @JoinTable(name = "Student_Course", 
     joinColumns = {@JoinColumn(name = "Course_ID", referencedColumnName = "id")}, 
     inverseJoinColumns = {@JoinColumn(name = "Student_ID", referencedColumnName = "id")}) 

     public Collection<Student> getStudents() { 
      return this.students; 
     } 

     public void setStudents(Collection<Student> students) { 
      this.students = students; 
     } 
    } 

但是,如果我在JoinTable中有一個屬性,例如每個學生在一個課程中都有一個分數。如何使用ManyToMany在EJB中創建它?
非常感謝您的關注!

+1

如果你的關係有屬性,那麼你應該把它建模爲實體。這個問題幾乎是一樣的:http://stackoverflow.com/questions/7602386/mapping-value-in-junction-table-to-entity/7603036#7603036即使代表關係的實體名稱(CourseAssignment)也很適合你案件。 – 2011-12-21 08:16:57

+3

這是不可能的,你不能添加屬性關係。如果您需要訪問連接表中的屬性,那麼該屬性屬於某個實體,因此您需要第三個實體。 – 2011-12-21 09:16:21

+0

對不起,我糾正了這一點。我還有一個問題,當我使用@Embeddable類作爲連接表的PK時,它不起作用(編譯失敗),有人說JPA2.0不支持它!請看看[jpa-eclipselink-manytomany-with-dat](http://stackoverflow.com/questions/4013397/jpa-eclipselink-manytomany-with-data),有什麼辦法可以使它工作嗎? – seaguest 2011-12-21 10:47:45

回答

4

這是不可能的,你不能添加屬性關係。如果您需要訪問連接表中的屬性,那麼該屬性屬於某個實體,因此您需要第三個實體。

3

這是可能的。

您只需要通過第三個實體將一對多和多對一映射的顯式組合替換爲多對多映射,這將代表兩個主要實體(學生和當然在你的例子)。

請仔細閱讀細節here

0

實體多對多的關係(商家和服務)。 這可以使用第三個實體如下來實現: -

@Entity 
@Table(name = "merchant") 
public class Merchant implements java.io.Serializable { 

    @OneToMany(fetch = FetchType.LAZY, mappedBy = "pk.merchant",targetEntity = MerchantService.class) 
    private Set<MerchantService> merchantServices = new HashSet<>(); 
} 

@Entity 
@Table(name = "merchant_service") 
@AssociationOverrides({ 
     @AssociationOverride(name = "pk.merchant", 
      joinColumns = @JoinColumn(name = "merchant_id")), 
     @AssociationOverride(name = "pk.service", 
      joinColumns = @JoinColumn(name = "service_id")) }) 
public class MerchantService implements java.io.Serializable { 

    @EmbeddedId 
    private MerchantServiceId pk = new MerchantServiceId(); 

    private boolean isActive; 

    public MerchantServiceId getPk() { 
     return pk; 
    } 

    public void setPk(MerchantServiceId pk) { 
     this.pk = pk; 
    } 

    @Transient 
    public Service getService() { 
     return getPk().getService(); 
    } 


    @Transient 
    public Merchant getMerchant() { 
     return getPk().getMerchant(); 
    } 


    public boolean isActive() { 
     return isActive; 
    } 

    public void setActive(boolean isActive) { 
     this.isActive = isActive; 
    } 

} 

@Embeddable 
public class MerchantServiceId implements java.io.Serializable { 

    private Merchant merchant; 
    private Service service; 

    @ManyToOne 
    public Merchant getMerchant() { 
     return merchant; 
    } 

    @ManyToOne 
    public Service getService() { 
     return service; 
    } 

} 

@Entity 
@Table(name = "service") 
public class Service implements java.io.Serializable { 

    @OneToMany(fetch = FetchType.LAZY, mappedBy = "pk.service",targetEntity = MerchantService.class) 
    private Set<MerchantService> merchantServices = new HashSet<>(); 

}