2013-02-13 38 views
1

我想弄清楚如何在我的應用程序中設置服務/ Dao層。我發現幾十種資源都以不同的方式如何做到這一點,並決定遵循這裏找到的模型:How should EntityManager be used in a nicely decoupled service layer and data access layer?@EJB workflowDao在服務層爲空

我不明白我錯過了什麼導致這個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),所以如果這看起來非常錯誤,請記住這一點。

+0

哪一行引發空指針異常? – mightyrick 2013-02-13 19:33:43

回答

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實體可以完成這個角色。

+0

爲什麼'@ Stateless'不正確?我經常看到DAO對象(http://tomee.apache.org/examples-trunk/rest-example/README.html) – Webnet 2013-02-13 19:48:13

+0

如果我不使用EJB,我該如何正確地將Dao提供給我的服務? – Webnet 2013-02-13 19:52:23

+0

@Webnet我澄清了我的答案。不是'@ Stateless'是錯誤的,它不是_enough_:類需要實現本地/遠程接口。如果您不打算使用EJB,只需在您的類中實例化DAO,不要注入它 - 或者將其注入爲POJO,而不是EJB(取決於您使用的框架)。 '@ EJB'註釋保留用於注入_actual_ EJBs – 2013-02-13 19:55:37

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:"; 
    } 

} 
+0

當你說'Jax-RS Resource'時,你指的是什麼?我的Dao如何與服務聯繫呢?應該是@EJB還是其他? – Webnet 2013-02-13 19:59:01

+0

我猜你的類具有 @GET @Produces (MediaType.TEXT_PLAIN) 是一個JAX-RS資源 – kfis 2013-02-13 20:00:17

+0

我接着說:@EJB WorkflowService workflowService;'到'MyController'類,而不是將其實例化的。它現在在'workflowService.save(workflow)'上拋出一個NPE。我以前從未使用過@EJB,所以我試圖在我去的時候弄清楚這一點...... – Webnet 2013-02-13 20:03:16