22

我目前正在创建一个 EJB3 数据访问类来处理我的 Java EE 6 应用程序中的所有数据库操作。现在,由于 Java EE 6 提供了新的ApplicationScoped注解,我想知道我的 EJB 应该有什么状态,或者它是否应该是无状态的。

让 DAO 成为@StatelessSession Bean 还是@ApplicationScopedBean 会更好吗?怎么样@Singleton?这些与 DAO 相关的选项之间有什么区别?

编辑: 我正在使用带有完整 Java EE 6 平台的 Glassfish 3.0.1

4

3 回答 3

17

让 DAO 成为 @Stateless Session Bean 还是 @ApplicationScoped Bean 哪个更好?@Singleton 呢?这些与 DAO 相关的选项之间有什么区别?

我不会对 DAO 使用无状态会话 Bean:

  1. EJB 由容器池化,因此如果每个池有 N 个实例和数千个表,那么您只会浪费资源(更不用说部署时的成本)。

  2. 将 DAO 实现为 SLSB 将鼓励 EJB 链接,从可伸缩性的角度来看,这不是一个好的实践。

  3. 我不会将 DAO 层绑定到 EJB API。

EJB 3.1中@Singleton引入的内容可以使事情变得更好,但我仍然不会将 DAO 实现为 EJB。我宁愿使用 CDI(也可能是自定义构造型,例如,请参阅这篇文章)。

或者我根本不会使用 DAO。JPA 的实体管理器是域存储模式的一种实现,并且在 DAO 中包装对域存储的访问不会增加太多价值。

于 2010-07-11T20:58:30.813 回答
2

经过一番重新思考,DAO 似乎并不是我想做的事情的正确名称。正如 Pascal 所说,也许它真的是一个 Facade。我刚刚找到了 Netbeans Petstore 示例 - 一个 JavaEE6 示例应用程序,请参见此处- 他们有一个ItemFacade负责从数据库中查找/创建/删除实体。它是一个无状态会话 Bean。看起来像这样:

@Stateless
public class ItemFacade implements Serializable {
    @PersistenceContext(unitName = "catalogPU")
    private EntityManager em;

    public void create(Item item) { ... }
    public void edit(Item item) { ... }
    public void remove(Item item) { ... }
    public Item find(Object id) { ... }
    public List<Item> findAll() { ... }
    public List<Item> findRange(int maxResults, int firstResult) { ... }
    public int getItemCount() { ... }
}

因此,作为一个结论,我不再称我的 DAO DAO 而是仅称为 PersonEJB(我认为“PersonFacade”可能会被误解)并将其设为 @Stateless,因为我认为 Netbeans 示例可以被认为是精心设计的。

于 2010-07-14T14:29:54.180 回答
0

@Pascal:在我看来,我的 DAO 对事务或安全性不“负责”,因为容器管理这些服务。我只是在我的 DAO 中注释方法(仅出于安全考虑,因为事务是自动处理的)。注释已经“责任”了吗?

好的,所以你让我重新考虑我的设计。希望它没问题并且不太离题,但也许它会有所帮助 - 这就是我今天使用 JEE6 的方式:

  • JSF 访问 CDI Bean,
  • CDI Bean 访问执行“业务逻辑”的 DAO-EJB
  • 所以目前我唯一的“业务逻辑”正在执行 CRUD,稍后我将为异步方法或计时器服务等关键任务添加一些其他 EJB。
  • 我的 DAO 是通用的,并使用 JPA2 Criteria Query 进行类型安全查询(根本没有字符串)
  • 我知道我不需要用于持久/更新/删除的 DAO(太简单了),但我的查询需要它;所以我把它们放在一起

这种方法有问题吗?

于 2010-07-11T23:33:28.677 回答