2011-09-11 115 views
7

在基於Spring/Hibernate的項目中,我們在兩個實體之間有一對多的關係。需要的操作是:應該避免Hibernate雙向關聯?

  • 找到孩子的父母;
  • 找到父母的孩子;
  • 當父母被刪除時,我們也需要刪除孩子;
  • 大衆創造孩子。

我們想出了兩種實現方法。

  1. Bidirectional association:子實體具有@ManyToOne柱連接起來,父母,和家長有孩子@OneToMany延遲加載集合。以上所有操作都可以在模型中進行:

    child.getParent(); 
    parent.getChildren(); //lazy loading 
    session.delete(parent); //cascade removal of the children does the trick here 
    session.save(parent); //cascade persist created the children 
    
  2. 單向協會:子實體具有@ManyToOne列其鏈接到父,但父沒有任何鏈接到孩子。大多數操作應該在服務方法進行:

    child.getParent(); //still in the model 
    Collection<Child> findChildren(Parent parent); //service method in ChildService 
    void deleteChildren(Parent parent); //service method in ChildService 
    void createChild(Parent parent, ... childAttributes); //service method in ChildService invoked for each new child. 
    

第一種方法似乎更容易實現(你可以重複使用Hibernate的級聯功能),但我們中的一些看到的雙向關聯的問題的潛在原因。

什麼應該是更好的設計選擇?是否有任何由雙向方法創造的衆所周知的問題,表現或設計?

+0

你知道一個解釋如何讓lazyloading工作的源代碼嗎?我在JSF項目中遇到了麻煩。 –

+1

「我們中的一些人將雙向關聯視爲問題的潛在原因」 - 您能否說出這些潛在問題? –

回答

3

如果你的查詢和Hibernate在場景中執行的查詢執行相同的操作時,我懶得加載孩子,我不明白你通過OneToMany關聯獲得了什麼。

如果您知道自己在做什麼以及每個方法在實體上對數據庫的查詢意味着什麼,那麼映射集合應該沒有任何問題。有時候遍歷它們是明智的,有時最好使用即席查詢來避免太多的往返數據庫。關鍵是瞭解發生了什麼。

只要能夠在HQL查詢中瀏覽它,並不一定要調用關聯的getter,分離也是非常有用的。

0

只要你處於懶惰加載真的適合你的情況,我還沒有看到雙向關係的真正問題。我曾經在一個使用Hibernate的Flex應用程序中工作,當數據序列化到客戶端時,雙向關係通常會導致整個數據庫被下載。

因人而異

0

通過@JB Nizet回答說,幾乎所有的,只是一兩件事:看您發佈的方法調用樣品,雙向方法將可能使你的業務邏輯代碼有點更具可讀性。

-1

是的, 應儘可能避免這種情況。如果你真的認爲,那是你的要求,那麼只能使用雙向。例如。僱主和部門,每個僱主都有一個部門,但部門有很多僱員。 emp必須知道他的部門,但這不是強制性的,部門也應該知道他們的部門。

+1

這似乎更像是一個評論,而不是一個答案。 – mattias