@EJB workflowDao在服务层中为null

时间:2013-02-13 19:29:14

标签: java ejb dao

我正在试图弄清楚如何在我的应用程序中设置Service / Dao图层。我发现了几十种资源都有不同的方法来决定如何做,并决定按照这里找到的模型:How should EntityManager be used in a nicely decoupled service layer and data access layer?

我无法弄清楚我错过了什么导致了这个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)所以如果这看起来非常糟糕,请记住这一点。

2 个答案:

答案 0 :(得分:1)

WorkflowDao不是EJB,它是带有@Stateless注释的POJO。很自然地,用@EJB注入它会失败,创建一个空workflowDao属性并最终产生一个NullPointerException

要使WorkflowDao成为一个成熟的EJB,除了具有@Stateless@Stateful注释外,还需要实现本地,远程或两个接口,并且必须对这些接口进行注释分别与@Local@Remote。有关详细信息,请参阅tutorial

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

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

答案 1 :(得分:1)

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

我建议你:

  • 注释您的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:";
    }

}