@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,那么管理器字段为null

但是,如果我没有标记@Stat,我可以注入管理器字段,并且该应用程序可以将数据保存到DB中,因此该应用程序可以使用。

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

这是接线应用程序的首选方法吗?

好吧,我正在考虑将实体管理员拿到生产者,以便可以共享

有帮助吗?

解决方案

问题是,如果我不将userService标记为@stateless,那么管理器字段为null

要进行注射,课程必须是 托管组件 例如企业豆,servlet,过滤器,JSF托管豆等或 CDI托管豆 (这是Java EE 6的新部分,您可以将任何类带有CDI托管的bean制作)。

因此,如果您不将JAX-RS端点变成EJB,那么如何启用注射?这很好地解释了 使用Glassfish V3的JAX-RS和CDI集成:

CDI托管豆的启用有两种方式:

  1. 由CDI实例化,由泽西岛管理的生命周期。注释 @ManagedBean 并可选地用泽西镜注释注释。

  2. 由CDI实例化和管理。用CDI示波器注释注释, @RequestScoped (不 @ManagedBean是必须的)

我还建议检查以下资源。

这是接线应用程序的首选方法吗?

我会说是的。 CDI非常好,...您不喜欢注射吗?

好吧,我正在考虑将实体管理员拿到生产者,以便可以共享

什么之间分享?为什么?在您的情况下,您应该使用 EntityManager 寿命范围为单个交易(a 交易的持久性上下文)。换句话说,不要共享它(不必担心为每个请求打开和关闭它,这不是一个昂贵的操作)。

参考

  • JPA 2.0规范
    • 第7.6节“由容器管理的持久性上下文”
    • 7.6.1节“容器管理的交易持续性上下文”
    • 第7.6.2节“由容器管理的扩展持久性上下文”

资源

其他提示

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top