2011-07-14 61 views
2

我正在使用EJB 3.1和JPA 2.0。EJB和JPA設計問題

我給你舉一個例子來解釋我的疑惑,並要求提示什麼是好的做法,什麼不是。

假設我有一個用戶Facade的EJB。所以,你有這樣的事情:

@Stateless 
public class UserRepository { 

    public User find(Long id) { 
    ...do user lookup using entitymanager. 
    } 

} 

好了,現在讓我們說我從這個返回用戶實體,該實體擁有的評論集(註釋也作爲一個實體)。

我可以使用findCommentsByUser(Long userId)方法創建註釋庫,或者我可以獲取用戶並調用getComments()方法。可能是這種情況很簡單,但我多次面對這個決定,有時不知道什麼是最好的。

另外,假設我想添加評論,是否應將其添加到實體具有的評論集合以及實體是否已合併,或者我應該使用addComment(Long userId, Comment newComment)方法嗎?

我正在尋找關於此的建議或最佳做法。如果您需要進一步澄清,請不要猶豫,問。

編輯:

我已經找到了評論到目前爲止有幫助,但是注意到這一點,它是不是真正的用戶和評論,我只是瞎編來解釋我的情況。這是關於混合兩種方法(我認爲不是這樣)還是比另一種更好。我喜歡「始終堅持存儲庫」的建議。但事實上,我在用戶實體中有一個fetchComments()存儲庫方法和getComments()爲同樣的功能創建入口點,所以我該如何處理? 此外,性能(1查詢與2查詢)並不重要,因爲我也將獲取用戶實體,所以它不像我實際上保存任何東西。

回答

1

您通常會將getComments()方法添加到您的用戶對象。當你想添加一個時,你可以將它添加到用戶集中,然後調用用戶對象的更新。

1

我認爲這很大程度上取決於需求,您希望如何對流程進行細化控制(這通常取決於性能要求和預期負載等)。 如果評論永遠不會被獨立檢索,我只會在User內保留它們作爲參考。

但是,如果您希望獲得評論,無論用戶如何,或者您想要執行其他與評論相關的查詢(如A組中用戶的所有評論),那麼我將創建單獨的CommentsRepository

如果您希望能夠將註釋添加到尚未從數據庫加載的用戶,但您擁有外鍵,則可能只是想像您所建議的那樣通過CommentsRepository添加註釋(還要添加註釋以並行用戶評論列表並將這兩個列表持久保存到數據庫中可能會導致「怪異行爲」)。

3

我們通常只使用應用程序中的分離實體,所以我們有一個數據訪問管理器來獲取和更新實體。然後我們知道,除非專門調用,否則我們在業務邏輯中執行的任何操作都不會被保留。我也會用用戶實體獲取註釋,但要確保在明確調用之前它不會被持久化。

2

我能有一個findCommentsByUser(龍 用戶id)方法的註釋庫,我也可以獲取用戶,並調用getComments()

我要說的是,從性能點的觀點,第一個替代方案稍好一些,因爲你不會讓用戶(1查詢)然後評論(另一個查詢)。第一個是在一個鏡頭中完成的。

在另一側中,我發現第二更可讀抽象,和面向對象方法。我會用這個。

1

有幾個需要考慮的因素,我希望我會在這裏爲你記錄它們。

  1. 域模型是EJB3中的重要考慮因素。在你的例子中,如果你看到你的域模型允許你懶惰地提取評論,因爲在任何流程中,你首先顯示用戶細節,然後顯示他的評論。
  2. 在某些情況下,您的集合(我指的是這裏的註釋)可能包含大量數據,在這種情況下,它幾乎沒有字符串數據的問題,所以不是主要關注的問題,但如果它真的是真正的應用程序數據,短暫的關係,並提供適當的方法來獨立獲取它們。
  3. 它從來沒有一個很好的做法,將您的集合內部實體bean暴露給外部世界,所以如果你OneToMany或ManyToMany關係,那麼你應該提供三種基本方法超過集合(添加,刪除,獲取)。
  4. 從get方法返回集合時應該使用Collections.unmodifiableCollection方法。
  5. 始終使用在實體內部使用集合時設置,請記住它們不允許重複。
  6. 在你的案例中,comments集合直接依賴於用戶,所以你應該在用戶中使用級聯類型來保存評論。
  7. 我不相信你爲什麼需要UserRepository,因爲em.find方法會爲你做好工作。
  8. 默認情況下,OneToMany關係fetchtype是懶惰的,所以如果你想做急切的加載,你需要指定它。

我希望這些指引能夠解決您的問題。

Regards, Amit