2014-07-16 33 views
3
@Entity 
public class Troop { 
@OneToMany(mappedBy="troop") 
public Set<Soldier> getSoldiers() { 
... 
} 

@Entity 
public class Soldier { 
@ManyToOne 
@JoinColumn(name="troop_fk") 
public Troop getTroop() { 
... 
} 

我做這樣的事情:休眠:哪一個是更好的方式:保存源或目標在多對一的關聯

Troup t = new Troup(); 
t.getSoldiers().add(soldier); 

這節省了部隊和士兵也。由於士兵是所有者,所以還增加了外鍵。但哪一個是更好的辦法,我的意思是使用節能託普或士兵:

Troop t = .....  // Get troop from session 
Soldier s = new Soldier(); 
s.setTroop(t); 

回答

1

你會在與這兩種方法獲得相同的結果。不過,我想,保存單個Soldier實體是一個小更高效:

  • 持久性提供並不需要遍歷集合
  • 代碼更好地對應於在DB會發生什麼 - 只有Soldier表得到反正更新。

但是,也許你應該考慮哪些業務適合理念更好,這意味着無論你在應用程序這一點與個人Soldiers工作或Troops

  • 添加SoldierTroop
  • 分配TroopSoldier

的差異可能是微妙的,但是這取決於你的業務情況下,或者一個可能是更容易閱讀和理解的解決方案。

+1

「持久性提供不需要搜索的變化來遍歷集合」 收集將已經得到走過,當我們做t.getSoldiers()。添加(士兵) – Ankit

+0

酷,不知道。已經放棄了最後部分的要點。我不太清楚Hibernate如何跟蹤引擎蓋下的髒東西。如果你知道一個很好的點對點參考,我會很感激鏈接。 – kostja

+1

從經驗來看,hibernate管理髒實體的方式並不是你應該關心的。它的混亂和吃飢餓的人一樣的記憶吃在培根自助餐,但它工作得很好,只要你的收藏不太大(<50,000件物品)。對於插入它並不重要,但您應仔細考慮從哪個方向調用選擇/更新,以避免n + 1選擇問題。 – JamesENL

1

因爲您有一個雙向關聯,所以需要強制來設置此關聯的雙方。你不應該只設置一邊,而將另一端置於不一致的狀態。

如果你把它變成一個單向關聯,則@ManyToOne側是更有效的管理:

Troop t = ..... 
Soldier s = new Soldier(); 
s.setTroop(t); 

使用@OneToMany方會要求你找人設置中添加新元素之前, 。這是強制性的,因爲Set不允許重複,因此需要初始化集合以執行唯一性策略。

總而言之:

  1. 對於你應該設置兩側雙向關聯。只設置一面可能會導致非常微妙的錯誤。

  2. @ManyToOne單向關聯執行比@OneToMany單向備選更好。