2010-04-10 105 views
6

問1)我們如何使用Hibernate建立三元關係模型?例如,我們如何使用Hibernate(或JPA)建模呈現here的三元關係?Hibernate中的三元關係

注意:我知道JPA 2已​​經添加了一些構建用於使用地圖建立三元關係。然而,這個問題假設JPA 1或Hibernate 3.3.x,我不喜歡用地圖來模擬這個。

ER Model http://db.grussell.org/co22001%20notes_files/image043.gif


ER Model with ternary relationships replaced http://db.grussell.org/co22001%20notes_files/image045.gif

理想我寧願我的模型是這樣的:

class SaleAssistant { 
Long id; 
//... 
} 

class Customer { 
Long id; 
//... 
} 

class Product { 
Long id; 
//... 
} 

class Sale { 
SalesAssistant soldBy; 
Customer buyer; 
Product product; 
//... 
} 

Q 1.1)

我們怎麼可以這樣變化,模型,其中每個銷售項目可能有多個產品? 2)一般情況下,我們如何建模n元組,n = 3與Hibernate的關係?

在此先感謝。

回答

11

Q1。我們如何使用Hibernate建立三元關係?例如,我們如何使用Hibernate(或JPA)對三元關係進行建模? (...)

我會改造與中間實體類的關聯(這是Hibernate的推薦方式)。適用於你的例子:

@Entity 
public class Sale { 
    @Embeddable 
    public static class Pk implements Serializable { 
     @Column(nullable = false, updatable = false) 
     private Long soldById; 

     @Column(nullable = false, updatable = false) 
     private Long buyerId; 

     @Column(nullable = false, updatable = false) 
     private Long productId; 

     public Pk() {} 

     public Pk(Long soldById, Long buyerId, Long productId) { ... } 

     // getters, setters, equals, hashCode 
    } 

    @EmbeddedId 
    private Pk pk; 

    @ManyToOne 
    @JoinColumn(name = "SOLDBYID", insertable = false, updatable = false) 
    private SaleAssistant soldBy; 
    @ManyToOne 
    @JoinColumn(name = "BUYERID", insertable = false, updatable = false) 
    private Customer buyer; 
    @ManyToOne 
    @JoinColumn(name = "PRODUCTID", insertable = false, updatable = false) 
    private Product product; 

    // getters, setters, equals, hashCode 
} 

Q1.1。我們如何模擬這種變化,其中每個銷售項目可能有許多產品?

我不會在這裏使用複合主鍵,併爲Sale實體引入PK。第二季度銷售價格指數爲:

Q2。一般來說,我們如何建模與Hibernate的n-ary,n> = 3關係?

我認爲我的答案是Q1。涵蓋這一點。如果沒有,請澄清。


更新:從沒有得到填充PK的領域OP

(......),因此我無法保存在數據庫銷售項目回答評論。我應該在銷售類中使用這樣的setter嗎? public void setBuyer(Customer cust){this.buyer = cust; this.pk.buyerId = cust。的getId(); }

你需要(從我原來的答覆我刪除了構造函數簡潔)創建一個新的Pk並設置它的Sale項目。我會這樣做:

Sale sale = new Sale(); 
Pk pk = new Pk(saleAssistant.getId(), customer.getId(), product.getId()); 
sale.setPk(pk); 
sale.setSoldBy(saleAssistant); 
sale.setBuyer(customer); 
sale.setProduct(product); 
... 

然後堅持sale

此外,在JoinColumn標註中,「name」字段引用的是哪個列?目標關係'pks或銷售表的自己的列名稱?

要爲複合Pk(即銷售表自己的列名)的屬性列,我們希望他們得到PK 和FK約束。

+0

謝謝你的迴應。但是當我使用這個時遇到問題:pk的字段沒有被填充,因此我無法將銷售項目保存在數據庫中。 我應該如何使用這樣的銷售類的setter? public void setBuyer(Customer cust){this.buyer = cust; this.pk.buyerId = cust.getId(); } 此外,在JoinColumn註釋中,哪些列是「名稱」字段引用的?目標關係'pks或銷售表的自己的列名稱? – Behrang 2010-04-11 02:00:34

0

您是否在使用數據庫生成的Customer,Product和SalesAssistant主鍵?這可能會導致問題,因爲它看起來像你試圖使用實際的數據庫身份,而不是讓Hibernate在實際持久化過程中解析對象引用。

上面的嵌入式PK對我來說看起來很奇怪,但我沒有機會嘗試一下。看起來這些列是重疊的,並且互相破壞。

我認爲只要有ManyToOne引用就足夠了。

另外,打開SQL語句調試並查看發送到數據庫的內容。