2012-10-12 89 views
5

多個@OneToMany我有兩個型號。休眠(JPA)爲同一型號

@Entity 
public class Student 
{ 
    @Id 
    @GeneratedValue(strategy=GenerationType.AUTO) 
    protected long id; 

    @? 
    protected Address homeAddress; 

    @? 
    protected Address schoolAddress; 
} 

@Entity 
public class Address 
{ 
    @Id 
    @GeneratedValue(strategy=GenerationType.AUTO) 
    protected long id; 

    @? 
    protected List<Student> students; 
} 

什麼JPA/Hibernate註解,我需要把上面homeAddressschoolAddressstudents,使協會工作?

當然我試過很多東西並沒有什麼工作。 例如,設置

@ManyToOne 
    @JoinColumn (name="student_homeAddress_id", updatable = false, insertable = false) 
    protected Address homeAddress; 

    @ManyToOne 
    @JoinColumn (name="student_schoolAddress_id", updatable = false, insertable = false) 
    protected Address schoolAddress; 

@OneToMany(cascade={CascadeType.PERSIST, CascadeType.MERGE, CascadeType.REFRESH}, fetch = FetchType.EAGER) 
    @JoinColumns({ 
    @JoinColumn(name = "student_homeAddress_id", referencedColumnName = "student_homeAddress_id"), 
    @JoinColumn(name = "student_schoolAddress_id", referencedColumnName = "student_schoolAddress_id")}) 
    @IndexColumn(name="students_index") 
    protected List<Student> students; 

yealds Unable to find column with logical name: student_homeAddress_id in org.hibernate.mapping.Table(Address) and its related supertables and secondary tables。 使用mappedBy也試過但這需要一個參數(不能做mappedBy="student_homeAddress_id, student_schoolAddress_id"

還研究了移動JoinColumnsStudent平板電腦,但我不知道註釋應該像對一對多和多對一什麼,因爲我有多個地址有哪些JoinColumns沒有多大意義

該做的工作,但並沒有創造協會是有這個事情:

@OneToMany(cascade={CascadeType.PERSIST, CascadeType.MERGE, CascadeType.REFRESH}, fetch = FetchType.EAGER) 
    @JoinColumn(name="address_id") 
    @IndexColumn(name="students_index") 
    protected List<Student> students; 

利用這一點,在數據庫存儲模型時,該即使存儲兩端(學生和地址模型),student_homeAddress_id和student_schoolAddress_id也始終爲空。

我的想法是在Address表中會有3個額外的列:student_homeAddress_id(StudentAddress的Student表中Student的id),student_schoolAddress_id(StudentAddress的Student表中的Student的id)和students_index(students列表中基於0的位置)。這應該就夠了,對嗎?

任何想法?

非常感謝!

回答

3

我們嘗試了mael的建議,但我們無法使其工作。

我們結束了以下工作的this

換句話說,我們有OneToMany關係:

Student

protected List<AddressStudentAssociation> addresses; 

Address

protected List<AddressStudentAssociation> students; 

而且在AddressStudentAssociation

@ManyToOne 
@PrimaryKeyJoinColumn(name="STUDENTID", referencedColumnName="id") 
private Student student; 
@ManyToOne 
@PrimaryKeyJoinColumn(name="ADDRESSID", referencedColumnName="id") 
private Address address; 

加上一個參數將一個地址與另一個地址分開(isHome)。

最後,在Student的內部,我們有public Address getHomeAddress(),它遍歷addresses列表並返回正確的地址。我們還必須使用註釋來使其工作。一般情況下不是最優的,但它起作用,我們已經花費了太多的時間來嘗試使事情發揮作用。 :|

4

如果您有需要關聯@OneToMany在多個領域,你應該使用@JoinTable因爲Hibernate可以產生的關係,2代表的實體。

從@JoinTable的Javadoc:

連接表通常在許多一對多和 單向一個一對多關聯的映射中使用。它也可以被用於映射 雙向多對1個/ 1-to-many關聯,單向 多到一個的關係,以及一個對一關聯(兩者 雙向和單向)。

當連接表是與該關係的持有端可嵌入 類映射關係中使用的,含有實體 而不是嵌入的類被認爲是 關係的所有者。

如果JoinTable註釋丟失, 註解元素的缺省值。連接表的名稱假定爲 使用下劃線連接在一起的關聯主表的表名 (擁有一方)。

拿這個例子:

@Entity 
@Indexed(index = "causa_penal") 
@Table(name = "causas_penales") 
public class CausaPenal implements Serializable { 



    @Id 
    @GeneratedValue(strategy = GenerationType.TABLE) 
    @Column(name = "id") 
    @DocumentId 
    private Integer id; 

    @Version 
    @Column(name = "opt_lock") 
    private Integer version; 

    @ManyToMany(cascade = { CascadeType.ALL }) 
    @JoinTable(name = "causapenal_imputados") 
    @IndexedEmbedded(depth = 1) 
    private List<ParteMaterial> imputados; 

    @ManyToMany(cascade = CascadeType.ALL) 
    @JoinTable(name = "causapenal_victimas") 
    @IndexedEmbedded(depth = 1) 
    private List<ParteMaterial> victimas; 

    //Getters and Setters 
} 

正如你所看到的,我有CausaPenal指向ParteMaterial兩次。但是我需要這些清單互相獨立。所以用@JoinTable告訴Hibernate,這個關係必須用4個表格來映射:CausaPenal實體的「causa_penal」,CausaPenal和映射到ParteMaterial實體的imputados字段的關係的「causa_penal_imputados」,以及victimas和最後,ParteMaterial Entity的表格。