2013-05-03 78 views
1

如何標註我的代碼有2個地址的人:JPA @OneToOne同類型

@Entity 
public Person { 

    // ... other attributes for a person 

    @OneToOne 
    public Address homeAddress; 

    @OneToOne 
    public Address workAddress; 
} 

@Entity 
public Address { 

    // ... other attributes for an address 

    @OneToOne 
    public Person person; 
} 

我可以使用OneToOne? 我是否必須使用此註釋中的選項?

+0

爲什麼要使用從地址到人員的反向指針?如果你刪除這個,你的實體是有道理的,假設一個地址可以被許多人共享。您可以在需要時查詢您正在查找的人員,而不是將他們保存在地址對象中。 「從Person p選擇p,其中p。工作地址=:地址「 – Chris 2013-05-03 13:31:40

回答

1

不幸的是,這是不可能實現與@OneToOne。原因:

持久性提供程序將有一個Person id爲兩個條目Address表。這不足以確定給定的Address屬於哪個關係。

最簡單的解決方案將是一個type字段(枚舉)添加到Address實體和映射地址與@OneToMany/@ManyToOne

爲了獲得家庭地址,您需要迭代地址並檢查類型。

或者,您可以創建額外的類型,如HomeAddressWorkAddress,它們將從Address派生。然後你可以保持@OneToOne關係,但最終會有兩個附加類型。

海事組織一個更清潔的實體關係映射不是一個足夠的理由這樣做,因爲你正在邀請一些問題。例如,HomeAddress永遠不能是WorkAddress

編輯:如果兩個Address ID存儲在Person表,你應該能夠使用@OneToOne關係。爲了確保連接地址實體的缺失和孤兒地址實體刪除,你可以使用級聯和孤兒去除:

@OneToOne(cascade=CascadeType.ALL, orphanRemoval=true) 

雖然它看起來像這樣可以確保有可能是沒有孤立Address記錄在數據庫中,它並不完全正確。孤兒刪除只在您連接實體時移除交易中的引用實體時才起作用。此外,它不適用於批量更新。 A DELETE FROM Person WHERE ...查詢將愉快地刪除人員,並且不會觸摸連接的地址。

+0

如果它可以幫助一個最佳的解決方案,我可以使用從'人'到'地址'的單向鏈接,但我想確保不會有未使用的」舊「地址在這種情況下的任何解決方案? – xnopre 2013-05-03 12:04:46

+0

@ xnopre-是的,使單向關係是一個很好的選擇,請參閱編輯 – kostja 2013-05-03 13:03:59

+0

是的,我的問題是與「批量」更新:我做一些POJO即分離的對象),然後合併和保存(我與PlayFramework V1)和「舊」未使用的地址不會被刪除,但如果我很好理解,這是正常的.... :-( – xnopre 2013-05-03 14:08:44

0

OneToOne意味着一個表有一個外鍵給另一個,但是你沒有指定哪一個,並且暗示它不是從地址 - >個人的真實1:1情況。員工是否有workAddress_ID和homeAddress_id字段?在這種情況下,有兩種不同的1:1。無效的是您的地址 - >員工1:1,因爲無法使用workAddress_ID和homeAddress_id關係。您可以通過讓地址擁有2個OneToOnes(私有地址),然後返回非空的應用程序使用的公共getPerson方法來解決此問題。設置人將需要着眼於通過親自對象OT知道其地址的1:1的填充,但它不會不管儘可能多的,因爲他們將無法控制關係:

public Address { 

    // ... other attributes for an address 

    @OneToOne(mappedby="workAddress") 
    private Person workPerson; 
    @OneToOne(mappedby="homeAddress") 
    private Person homePerson; 

    public Person getPerson() { 
     return workPerson==null? homePerson:workPerson; 
    } 
    public void setPerson(Person p) { 
     workPerson=null; 
     homePerson=null; 
     if (p !=null) { 
      if (p.getHomeAddress()==this) { 
       homePerson=p; 
      } else { 
       workPerson=p; 
      } 
     } 
    } 
} 
+0

精確度:我正在使用「PlayFramework V1」,我的對象擴展了'play.db.jpa.Model'並有一個「Id」字段。我不想修改添加2個或更多'Person'字段的'Address' – xnopre 2013-05-03 14:30:04