JavaEE6 DAO:应该是@Stateless还是@ApplicationScoped?

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

让DAO成为@Stateless会话Bean或@ApplicationScoped Bean会更好吗? @Singleton怎么样? 这些与DAO相关的选项有何不同?

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

让DAO成为@Stateless会话Bean或@ApplicationScoped Bean会更好吗? @Singleton怎么样? 这些与DAO相关的选项有何不同?

我不会将无状态会话Bean用于DAO:

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

  2. 将SLO实现为SLSB将鼓励EJB链接,从可扩展性的角度来看,这不是一个好的做法。

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

EJB 3.1中引入的@Singleton可以使事情变得更好但我仍然不会将DAO实现为EJB。 我宁愿使用CDI(也许是一个自定义的刻板印象,例如参见这篇文章 )。

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

经过一番反思,似乎DAO实际上并不是我想做的正确名称。 帕斯卡尔说,也许它真的是一个门面。 我刚刚找到了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 findAll() { ... } public List findRange(int maxResults, int firstResult) { ... } public int getItemCount() { ... } } 

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

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

好的,所以你让我重新思考我的设计。 希望它没关系,也不是太偏离主题,但也许有帮助 – 这就是我今天使用JEE6的方式:

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

这种方法有问题吗?