【问题标题】:Using CDI + WS/RS + JPA to build an app使用 CDI + WS/RS + JPA 构建应用程序
【发布时间】:2010-09-19 03:13:59
【问题描述】:
@Path(value = "/user")
@Stateless
public class UserService {

    @Inject
    private UserManager manager;

    @Path(value = "/create")
    @GET
    @Produces(value = MediaType.TEXT_PLAIN)
    public String doCreate(@QueryParam(value = "name") String name) {
        manager.createUser(name);

        return "OK";
    }
}

这是用户管理器的实现

public class UserManager {

    @PersistenceContext(unitName = "shop")
    private EntityManager em;

    public void createUser(String name) {
        User user = new User();
        user.setName(name);
        // skip some more initializations 
        em.persist(user);
    }
}

问题是,如果我没有将 UserService 标记为 @Stateless,那么 manager 字段为 null

但是如果我标记@Stateless,我可以注入管理器字段,并且应用程序可以正常工作,因为我可以将数据保存到数据库中

只是想知道,这背后的原因是什么?

这是连接应用程序的首选方式吗?

好吧,我正在考虑将 EntityManager 拉出给生产者,以便可以共享

【问题讨论】:

    标签: jpa jakarta-ee java-ee-6 jax-rs cdi


    【解决方案1】:

    问题是,如果我没有将 UserService 标记为 @Stateless,那么 manager 字段为 null

    要进行注入,该类必须是一个托管组件,例如 Enterprise Bean、Servlet、过滤器、JSF 托管 bean 等或 CDI 托管 bean(此是 Java EE 6 的新部分,您可以使用 CDI 使任何类成为托管 bean。

    那么,如果您不将 JAX-RS 端点设为 EJB,如何启用注入? JAX-RS and CDI integration using Glassfish v3 很好地解释了这一点:

    CDI 管理 bean 有两种方式 已启用:

    1. 由 CDI 实例化,生命周期由 Jersey 管理。注释 @ManagedBean 并可选择注释 带有泽西岛范围注释。

    2. 由 CDI 实例化和管理。使用 CDI 范围注释进行注释, 喜欢@RequestScoped(没有@ManagedBean 是必需的)

    我还建议查看以下资源。

    这是连接应用程序的首选方式吗?

    我会说是的。 CDI 非常好,而且……你不喜欢注射吗?

    好吧,我正在考虑将 EntityManager 拉出给生产者,以便可以共享

    在什么之间共享?为什么?在您的情况下,您应该使用EntityManager,其生命周期仅限于单个事务(事务范围的持久性上下文)。换句话说,不要共享它(也不要担心为每个请求打开和关闭它,这不是一个昂贵的操作)。

    参考文献

    • JPA 2.0 规范
      • 第 7.6 节“容器管理的持久性上下文”
      • 第 7.6.1 节“容器管理的事务范围持久性上下文”
      • 第 7.6.2 节“容器管理的扩展持久性上下文”

    资源

    【讨论】:

    • 非常好的和详细的答案,还有一件事要澄清,EM 的“共享”,假设我有另一个使用相同 PU 的 OrderService,我不想重复 @PersistenceContext( unitName = "shop") 而我想把它作为@Inject EntityManager,我该怎么做?
    • @Dapeng AFAIK,如果在使用@PersistenceContext的组件范围内只定义了一个持久性单元,则不需要在@PersistenceContext中指定unitName,否则你需要指定。
    【解决方案2】:

    【讨论】:

      猜你喜欢
      • 2015-01-11
      • 1970-01-01
      • 2014-11-07
      • 1970-01-01
      • 1970-01-01
      • 2012-01-19
      • 2013-04-19
      • 2013-11-21
      • 1970-01-01
      相关资源
      最近更新 更多