2014-09-24 122 views
1

我有三個表,Member,AddressMem_AddrMemberAddress實體通過Mem_Addr表映射/連接。多對多。休眠映射 - 連接表沒有@Id

我爲MemberAddress以下實體:

@Entity 
@Table (name="Member") 
public class Member{ 

    @Id //.... 
    private Integer mem_id; 

    @OneToOne 
    @JoinTable  (name = "Mem_Addr", 
      joinColumns = @JoinColumn(name = "addr_id"), 
     inverseJoinColumns = @JoinColumn(name = "mem_id")) 
    Set<Address> addresses = new HashSet<Address>; 
    ... 
} 

Mem_Addr表(它沒有相關的實體)。

addr_id // (PK) Sequence 
mem_id // (FK to mem_id in Member table) 
.... 
.... 

Address實體。

@Entity 
@Table(name="Address") 
public class Address { 

    private String addr_id; // Foreign Key to addr_id in Mem_addr table 
    private String address1; 
    ... 
} 

我在Address表/實體中沒有ID。 (請不要問我關於這個設計的問題,它現在不可改變。)

所以當我加載成員時,我想加載該成員的所有地址位置。

解決方案是什麼?

編輯:更多信息...

基本上一些Member旨意在Mem_Addr表中的新條目。對於Mem_addr表中的每個條目,將在Address表中有條目。

要獲取成員的地址,我需要引用Mem_Addr。 Mem_Addr具有addr_id作爲主鍵,地址具有addr_id作爲外鍵。

+1

Address實體中是否存在addr_id,因爲我在Mem實體中看到您正在調用它? – Rika 2014-09-24 20:03:13

+0

@Rika你是對的..我打錯了。糾正。 – 2014-09-24 20:05:31

+0

我想你可能可以連接沒有Ids,但它必須有Embeddable註釋,請看這裏http://stackoverflow.com/questions/767277/hibernate-and-no-pk – Rika 2014-09-24 20:13:42

回答

1

不幸的是,沒有辦法,Hibernate需要你的表有主鍵。您可以檢出this document

1

您確定Mem_Addr表是多對多的,而不是一對多嗎?我看不出一個Address可以用一個以上的Member相關...

假設它實際上是一個對許多人來說,映射你的Address實體既通過@SecondaryTable註釋的Mem_AddrAddress表描述在Hibernate Mapping Two Tables to One Class中,將id映射到Mem_Addr.addr_idMember通過Mem_Addr.mem_id,並且其他所有內容通過Address中的其他字段映射。

我沒有這樣做,但我相信它會工作:

@Entity 
@Table(name = "Address") 
@SecondaryTable(name = "Mem_Addr", pkJoinColumns={ 
    @PrimaryKeyJoinColumn(name="addr_id" referencedColumnName="addr_id") 
}) 
class Address { 
    @Id 
    @Column 
    private String addr_id; 

    .... 
} 
+0

其可能性。因爲在保險領域,多個客戶可以在同一地址。好吧,如果我假設它將成爲@OneToMany,但你的解決方案並不明確。你能詳細說明嗎? – 2014-09-24 20:30:41

+0

我還沒有這樣做(幸好我總是擁有比你堅持的更合理的模式),但是你應該可以使用@SecondaryTable註解來實現這一點,如http:// stackoverflow的.com /問題/ 1667918 /休眠映射-兩表對一類。 – Tim 2014-09-24 20:43:41

+0

另外,我同意在現實世界中,可能有多個「成員」用於單個「地址」。但我不相信在你的數據庫模式中是可能的(即使這個「Address」的值是相同的,你也必須爲每個Member對象創建一個Address對象),這就是爲什麼希望您將被允許在將來的某個時刻更改該架構。 – Tim 2014-09-24 20:46:43

1

好吧,因爲插入和更新是沒有必要的,下面的(理論上)或許應該工作:

@Entity 
@Table(name = "Address") 
class Address { 

@Id 
private AddressKey id; 

public void setId(AddressKey id) { 
this.id = id; 
} 

public void getId() { 
return id; 
} 
} 

@Embeddable 
class AddressKey implements Serializable { 
    @Column(name = "addr_id") 
    private String addrId; //also the underscore should be deleted 

    @Column(name = "address_1") 
    private String address1; 



    } 

這是發現那些沒有主鍵的表一個解決方法。正如你所看到的,它幾乎使一個虛假的Id。

+0

如果我們不擔心插入和更新,那麼爲什麼要打擾@Embeddable?只需將'addr_id'映射爲@Id並完成它。 (此外,'address1'不是表的主鍵的一部分,所以我不確定爲什麼你將它包含在@Embeddable ...) – Tim 2014-09-24 21:35:50

+0

但是,如何將地址映射到成員表。這兩者之間沒有聯繫。這可能是一個簡單的事情.. ..你讓我..我是一個新手Hibernate :-) – 2014-09-24 21:36:46

+1

雖然,我認爲這是一個壞的決定,故意映射一個不能用於Hibernate實體寫入數據庫,即使你認爲你不需要這種能力。在某些情況下,你可能會有這種可能性,即使你真的從不在生產中需要它們,如果你想將一些測試數據寫入虛擬數據庫以便在單元測試中使用,該怎麼辦?我認爲採用這種方法在其他方法也可行時不會出現這些缺點,但我們都會做出自己的選擇,這是您的呼叫。 – Tim 2014-09-24 21:38:55