EJB和JPA设计问题

时间:2011-07-14 19:17:14

标签: java design-patterns jpa ejb

我正在使用EJB 3.1和JPA 2.0。

我会举一个例子来解释我的怀疑,并提出一些好的做法和不做的提示。

假设我有一个用户Facade的EJB。所以你有这样的事情:

@Stateless
public class UserRepository {

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

}

好吧,现在让我说我从这里返回User实体,并且该实体有一组注释(Comment也是一个实体)。

我可以使用findCommentsByUser(Long userId)方法创建一个Comment Repository,或者我可以获取用户并调用getComments()方法。可能这种情况很简单,但我有时会多次面对这个决定而不知道什么是最好的。

另外,假设我要添加评论,是否应将其添加到实体所拥有的评论集合中并将实体合并,还是应该使用addComment(Long userId, Comment newComment)方法?

我正在寻找有关此问题的建议或最佳做法。如果您需要进一步澄清,请不要犹豫。

编辑:

我发现这些评论到目前为止很有帮助,但是请注意这一点,它并不是关于用户和评论,我只是解释了我的情况。这是关于混合两种方法(我认为不是这种方法)还是比另一方更好的方法。我喜欢“始终坚持通过存储库”的建议。但是我有一个fetchComments()存储库方法和用户实体中的getComments()创建了相同功能的入口点,所以我该如何处理呢? 此外,性能(1个查询对2个查询)并不重要,因为我也将获取用户实体,所以它不像我实际上正在保存任何东西。

5 个答案:

答案 0 :(得分:3)

我们通常只在我们的应用程序中使用分离的实体,因此我们有一个数据访问管理器来获取和更新实体。然后我们知道,除非特别要求,否则我们在业务逻辑中所做的任何事情都不会被持久化。我还会获取用户实体的注释,但要确保在显式调用之前不会持久化。

答案 1 :(得分:2)

  

我可以使用findCommentsByUser(Long   userId)方法,或者我可以获取用户并调用getComments()

我会说从性能的角度来看,第一种选择略胜一筹,因为你没有用户(1个查询),然后是评论(另一个查询)。第一个是单次拍摄。

另一方面,我发现第二个可读抽象面向对象方法。我会用这个。

答案 2 :(得分:1)

通常会将getComments()方法添加到用户对象中。如果要添加一个,则将其添加到用户集,然后在用户对象上调用update。

答案 3 :(得分:1)

我认为这在很大程度上取决于要求,您希望如何对流程进行细粒度控制(这通常取决于性能要求和预期负载等)。 如果永远不会独立检索注释,我只会将它们作为User内的参考。

但是,如果您想要获取评论而不考虑用户,或者您想要执行其他一些与评论相关的查询(例如A组中用户的所有评论),那么我会创建单独的{{1} }。

如果您希望能够将注释添加到未从数据库加载的用户,但您拥有外键,则可能只需要像您建议的那样通过CommentsRepository添加注释(同时添加对用户注释列表并行注释并将这两个列表保存到DB中可能会导致“奇怪的行为”。)

答案 4 :(得分:1)

需要考虑几个因素我希望我能在这里为您记录。

  1. 域模型是EJB3中的重要考虑因素。在您的示例中,如果您看到您的域模型允许您懒惰地获取评论,因为在任何流程中您首先显示用户详细信息,然后显示他的评论。
  2. 在某些情况下,你的收藏(我在这里指的是评论)可能包含大量数据,在这种情况下,它几乎不是字符串数据的问题所以不是主要问题,但如果它是真正的应用程序数据那么总是选择瞬态关系并提供适当的方法来独立获取它们。
  3. 将实体bean中的集合暴露给外部世界从来都不是一个好习惯,所以如果你有OneToMany或ManyToMany关系,那么你应该提供三个基本方法而不是集合(添加,删除,获取)。
  4. 从get方法返回集合时应使用Collections.unmodifiableCollection方法。
  5. 在实体中使用集合时始终使用Set,请记住它们不允许重复。
  6. 在您的情况下,评论集合直接依赖于用户,因此您应该在用户中使用级联类型来保存评论。
  7. 我不相信你为什么需要UserRepository,因为em.find方法会为你做好工作。
  8. 默认情况下,OneToMany关系fetchtype是懒惰的,所以如果你想做急切的加载,你需要指定它。
  9. 我希望这些指南能够解决您的问题。

    此致 阿米特