2011-07-14 63 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