1

我试图弄清楚如何在我的应用程序中设置服务/道层。我找到了几十个资源,它们都有不同的方法,并决定遵循这里找到的模型:EntityManager 应该如何在良好解耦的服务层和数据访问层中使用?

我无法弄清楚导致此 NPE 的原因是什么。

用法:

@Path("/helloworld")
public class MyController {
    @GET
    @Produces(MediaType.TEXT_PLAIN)
    public String TestRequest() {
        Workflow workflow = new Workflow();
        workflow.setName("test");

        WorkflowService workflowService = new WorkflowService();
        workflowService.save(workflow);

        return "Workflow ID:";
    }
}

我的道:

@Stateless
public class WorkflowDao {

    @PersistenceContext(unitName = "unit")
    private EntityManager entityManager;

    public int save(Workflow workflow) {
        entityManager.persist(workflow);
        return workflow.getId();
    }
}

我的服务:

@Stateless
public class WorkflowService {

    @EJB
    WorkflowDao workflowDao;

    public int save(Workflow workflow) {
        int id = workflowDao.save(workflow); //throws NullPointerException because workflowDao is null
        return id;
    }
}

这是我第一次设置 Java 项目(之前只在 1 上工作过,并且使用了 Spring),所以如果这看起来非常错误,请记住这一点。

4

2 回答 2

1

WorkflowDao不是 EJB,而是带有@Stateless注释的 POJO。所以很自然地,注入它@EJB失败,创建一个 nullworkflowDao属性并最终产生一个NullPointerException.

WorkflowDao成为一个成熟的 EJB,除了具有@Statelessor@Stateful注释之外,它还需要实现本地、远程或两者的接口,并且这些接口必须分别用@Local和注释@Remote。详情请参阅教程

此外,很可能(这可能取决于应用程序服务器)您必须在应用程序的 xml 描述符文件中注册 EJB - 例如,在 web.xml 的<ejb-local-ref>元素中。

作为旁注 - 将 EJB 用作 DAO 不是一个好主意,EJB 通常用于实现业务逻辑(确实,可以从这里调用持久/合并操作)但现在实际的持久层是使用 JPA 实现的. 换句话说,WorkflowService应该是EJB服务,不需要向其中注入 EJB,也不需要单独的 DAO 层——JPA 实体完成了这个角色。

于 2013-02-13T19:33:57.737 回答
1

如果您手动实例化您的 WorkflowService,容器将不会执行任何注入,因为您的 WorkflowService 不受容器管理。

我建议你:

  • 注释您的 Jax-RS 资源 @Stateless

  • 通过 @EJB 作为成员注入您的 WorkfloService

不再需要实现本地或远程接口

@Path("workflows")
@Stateless
public class WorkFlowResource{
  @EJB
  WorkflowService workflowService;
  @GET
  @Produces(MediaType.TEXT_PLAIN)
  public String TestRequest() {
    Workflow workflow = new Workflow();
    workflow.setName("test");
    workflowService.save(workflow);
    return "Workflow ID:";
    }

}
于 2013-02-13T19:57:55.780 回答