2013-01-03 163 views
0

假設我想要一個複合關鍵字作爲街道,城市的採購訂單實體。使用複合鍵休眠

下面是我確定如何做,

@Embeddable 
    public class BillingAddress implements Serializable { 

     private String street; 
     private String city; 

     public BillingAddress(){ 

     } 

     public BillingAddress(String street, String city) { 
      this.street = street; 
      this.city = city; 
     } 
     //with getters and setters 
} 



@Entity 
@IdClass(BillingAddress.class) 
public class PurchaseOrder { 

    public PurchaseOrder(BillingAddress billingAddress) { 
     street = billingAddress.getStreet(); 
     city = billingAddress.getCity(); 

    } 

    @Id 
    @AttributeOverrides({ 
      @AttributeOverride(name = "street", column = @Column(name = "STREET")), 
      @AttributeOverride(name = "city", column = @Column(name = "CITY")) }) 
    private String street; 
    private String city; 
    private String itemName; 

    public String getItemName() { 
     return itemName; 
    } 

    public void setItemName(String itemName) { 
     this.itemName = itemName; 
    } 

} 

我想了解什麼是真正@AttributeOverrides註解嗎?即使我更改爲colomn名稱STREET1我仍然看到列創建名稱STREET。那麼在這裏做什麼是column = @Column(name =「STREET」))。

而且不是constructore服用BillingAddress我可以把它像PurchaseOrder類權像場,

public class PurchaseOrder { 
    BillingAddress billingAddress; 

} 

在這種情況下,如何去改變? 我還需要有私人字符串街道;私人絃樂城;在PurchaseOrder中?

最後我讀到,應該避免在使用複合主鍵的新數據庫系統設計中使用組合鍵,這是爲了映射遺留數據庫表而不更改數據庫表結構的權利?這種說法是否有效?

//編輯問題

節約採購訂單的結算地址是在外地,

PurchaseOrder purchaseOrder = new PurchaseOrder(); 
purchaseOrder.setItemName("name"); 

BillingAddress billingAddress = new BillingAddress(); 
billingAddress.setCity("c1"); billingAddress.setStreet("s1");                purchaseOrder.setBillingAddress(billingAddress); 
session.save(purchaseOrder); 

回答

0

那麼,你的PurchaseOrder類不從任何類型的映射實體延伸,也不做屬性,你是(當前)應用@AttributeOverride到。所以,沒有什麼可以實際覆蓋,並且您的JPA提供者完全忽略了註釋。我想你要做的是爲實體定義一個嵌入式ID,同時覆蓋該ID的一些列映射。你可以用一些修改當前的代碼做到這一點:

@Entity 
public class PurchaseOrder { 
    @EmbeddedId 
    @AttributeOverrides({ 
      @AttributeOverride(name = "street", column = @Column(name = "BILLING_STREET")), 
      @AttributeOverride(name = "city", column = @Column(name = "BILLING_CITY")) }) 
    private BillingAddress billingAddress; 

    private String itemName; 

    // Constructors, Getters/Setters 
} 

請注意,我與你當前的例子改變了重寫屬性的名稱,因爲嵌入式ID名稱和覆蓋的名稱是相同的。

+0

我已經與auther中的PurchaseOrder實體提及街道和城市領域,「重複的代碼,當然,對街道和城市兩個私有數據成員下面的文章。這種重複是創建組合鍵所必需的。「 http://www.ibm.com/developerworks/library/os-hibernatejpa/ – FrankD

+0

如果PurchaseOrder和BillingAddress之間的關係在PuchaseOrder不能存在於帳單地址的情況下(如果您刪除帳單地址採購訂單應該被刪除腳本的情感)在這種情況下,我需要將結算地址傳遞給採購訂單構造函數,而不是將其作爲字段顯示在代碼中? – FrankD

+0

該教程似乎有一個錯誤 - 在使用@IdClass時,您需要映射組合鍵中所有組合鍵的所有元素。對於第二個問題,JPA框架在保存實體之前驗證實體 - 這包括驗證嵌入ID是否已設置。 – Perception

1

有少的問題你問,我試圖去通過所有這些,回答每一個:

是什麼@AnnotationOverride辦?

答案在這裏:What does @AttributeOverride mean?

第二個問題是有點不清楚我,但我相信你問你是否要包括從PurchaseOrder類複合鍵中的所有領域。

不,我不這麼認爲。這裏有一個例子,我把它放在一起真快:

@Entity 
@Table(name = "PURCHASE_ORDER") 
public class PurchaseOrder{ 

    @Id 
    private BillingAddress billingAddress; 

    //getters & setters 

    @Embeddable 
    public static class BillingAddress implements Serializable { 
     @Column(name = "street") 
     private String street; 
     @Column(name = "city") 
     private String city; 
     @Column(name = "itemName") 
     private String itemName; 

     //getters & setters 

    } 
} 

不要擔心語法,只是結構。您甚至可以將額外的字段添加到不是ID的PurchaseOrder中。

我應該使用組合鍵嗎?

答案在這裏:Should I use composite primary keys or not?