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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3223112/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-30 00:51:52  来源:igfitidea点击:

JavaEE6 DAO: Should it be @Stateless or @ApplicationScoped?

javajakarta-eeejbjava-ee-6ejb-3.1

提问by Ingo Fischer

I'm currently creating an EJB3 Data Access Class to handle all database operations in my Java EE 6-application. Now, since Java EE 6 provides the new ApplicationScopedannotation, I wonder what state my EJB should have, or if it should be stateless.

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

Would it be better to let the DAO be a @StatelessSession Bean, or an @ApplicationScopedBean? What about @Singleton? What are the differences between these options related to a DAO?

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

EDIT:I'm using Glassfish 3.0.1 with the full Java EE 6 platform

编辑:我将 Glassfish 3.0.1 与完整的 Java EE 6 平台一起使用

采纳答案by Pascal Thivent

Whould it be better to let the DAO be a @Stateless Session Bean, or an @ApplicationScoped Bean? What about @Singleton? What are the differences between these options related to a DAO?

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

I would NOT use Stateless Session Beans for DAOs:

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

  1. EJBs are pooled by the container so if you have N instances per pool and thousands of tables, you're just going to waste resources (not even to mention the cost at deploy time).

  2. Implementing DAOs as SLSB would encourage EJB chaining which is not a good practice from a scalability point of view.

  3. I would not tie the DAO layer to the EJB API.

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

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

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

The @Singletonintroduced in EJB 3.1 could make things a bit better but I would still not implement DAOs as EJBs. I would rather use CDI (and maybe a custom stereotype, see this articlefor example).

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

Or I wouldn't use DAOs at all. JPA's entity manager is an implementation of the Domain Storepattern and wrapping access to a Domain Store in a DAO doesn't add much value.

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

回答by Ingo Fischer

After some rethinking, it seems like DAO is actually not the right name for what i wanted to do. Maybe it really is a Facade, as Pascal said. I just found the Netbeans Petstore Example - a JavaEE6 sample application, see here- where they have an ItemFacadewhich is responsible for finding/createing/removing entities from the database. It's a Stateless Session Bean. Looks like this:

经过一些反思,似乎 DAO 实际上并不是我想做的事情的正确名称。也许它真的是一个 Facade,正如 Pascal 所说。我刚刚找到了 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() { ... }
}

So as a conclusion i don't call my DAO DAO anymore but instead just for example PersonEJB (i think "PersonFacade" could be misunderstood) and make it also @Stateless, as i think the Netbeans example can be considered as well-designed.

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

回答by Ingo Fischer

@Pascal: In my opinion my DAO isn't "responsible" of transaction or security, as the container manages these services. I'm just annotating the methods in my DAO (only for security, as transactions are handled automatically). Are annotations already "responsibility"?

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

Okay so you make me re-think about my design. Hope its okay and not too off-topic, but maybe it helps - this is how i'm using JEE6 today:

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

  • JSF accesses a CDI Bean,
  • the CDI Bean accesses the DAO-EJB which does the "business logic"
  • so currently my only "business logic" is doing CRUD, later i'll add some other EJBs for critical tasks like asynchronous methods or Timer Services.
  • my DAO is generic and uses the JPA2 Criteria Query to do typesafe queries (no strings at all)
  • I know that i don't need a DAO for persist/update/remove (too simple), but i need it for my queries; so i just put them together
  • JSF 访问 CDI Bean,
  • CDI Bean 访问执行“业务逻辑”的 DAO-EJB
  • 所以目前我唯一的“业务逻辑”是做 CRUD,稍后我将添加一些其他 EJB 用于关键任务,如异步方法或定时器服务。
  • 我的 DAO 是通用的,并使用 JPA2 Criteria Query 进行类型安全查询(根本没有字符串)
  • 我知道我不需要 DAO 来进行持久/更新/删除(太简单了),但我需要它来进行查询;所以我只是把它们放在一起

Is something wrong with that approach?

这种方法有什么问题吗?