1

アプリケーションで Service/Dao レイヤーをセットアップする方法を見つけようとしています。私はそれを行う方法がすべて異なる数十のリソースを見つけ、ここにあるモデルに従うことにしました: How should EntityManager be used in a pretty 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 を使用していました)、これがひどく間違っているように見える場合は注意してください。

4

2 に答える 2

1

WorkflowDaoEJB ではなく、@Statelessアノテーション付きの POJO です。当然、それを注入すると@EJB失敗し、nullworkflowDao属性が作成され、最終的にNullPointerException.

WorkflowDao本格的な EJB にするためには、 または アノテーションを持つことに加えて、@Statelessローカル@Stateful、リモート、または両方のインターフェースを実装する必要があり、それらのインターフェースにはそれぞれ@Localおよびのアノテーションを付ける必要があり@Remoteます。詳細はチュートリアルを参照してください。

また、おそらく (これはアプリケーション サーバーに依存する可能性があります)、アプリケーションの xml 記述子ファイル (たとえば、web.xml の<ejb-local-ref>要素) に EJB を登録する必要があります。

補足として、EJB を DAO として使用することはお勧めできません。通常、EJB はビジネス ロジックの実装に使用されます (実際、永続化/マージ操作はここから呼び出すことができます) が、現在の実際の永続化レイヤーは JPA を使用して実装されています。 . つまり、EJBWorkflowServiceサービスである必要があり、そこに 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 に答える