0

EJBコンテナによって管理されるentityManagerの使用に問題があります。Persistence ContextからのEntityManagerのヌルポインタ例外Java EE

-domain - エンティティ・クラスおよびDAO実装は、EJBなどのインタフェースであります。私の耳には

iは、3つのモジュールがあります。

-services - ライブラリの例外(データベース例外など)に基づいてビジネス例外を呼び出し、リクエストの処理に関連するロジックがあります。

-Rest Services - 私はいくつかのビジネスオブジェクトを送受信するために休憩のエンドポイントを持っていました。

主な問題は、サービス層でEJBを使用することです。残りのエンドポイントクラス、サービスクラス、およびDAOクラスをEJBとして宣言できます。しかし、その方法では、データベースに関連する例外をキャッチすることはできません。なぜなら、私がredFlashで提供されたEJBコンテナでtransactionRollback例外を取得し、この例外がコミットトランザクションに存在するからです。

私はサービスクラスから@Statelessアノテーションを削除することを考えましたが、それを行うと、EJBコンテナは、DAOクラスにentityManagerを挿入しません。また、サービスクラスで@Injectアノテーションを使用しようとしましたが、DaoクラスのentityManagerで同じNullPointer例外が発生します。

私は私のプロジェクトで、サンプルコードの実装を追加してい以下:

DAOクラス:

@Stateless 
public class CardDaoImpl implements CardDao { 

@PersistenceContext(unitName = "test") 
protected EntityManager em; 

public CardBase addCardToDatabase(CardBase card) { 
    em.persist(card); 
    return card; 
} 

サービスクラス(ここでは、私はbusinessExceptionsを処理する):

@Stateless 
public class TestService implements TestServiceIf { 

@EJB(beanInterface = CardDao.class) 
private CardDao dao; 

@Override 
public CardBase addCard(CardBase card) { 
    dao.addCardToDatabase(card); 
    return card; 
} 

} 

休憩エンドポイントクラス:

@Stateless 
@Path("/test") 
public class Test { 

@EJB(beanInterface = TestServiceIf.class) 
private TestServiceIf service; 

@GET 
@Path("/test") 
@Produces(MediaType.APPLICATION_JSON) 
public String addCard() { 
    CardBase card = new SampleCard(); 
    //Setting card object fields// 
    service.addCard(card); 
    return "Hello"; 
} 

}

これは私が発見した唯一の解決策です。しかし、私のbusinnesExceptionsを投げて何がありますか?おそらく、このサービス層にそれらを投げるのは良い習慣ではないでしょうか?

+0

あなたのサーバーとあなたのEJBのバージョンは何ですか?残念なことに、サーバーによると、EJBの仕様であっても固有性があります。 – davidxxx

+0

私はWildfly 10を使用しています。このアプリケーションサーバーのモジュールでは、EJB3.2 APIが見つかりました –

答えて

1

EJB 3.Xでは、ejbメソッドで発生する例外についていくつかの特長があります。

-services - があり、私は( 例えば、データベース例外の)ライブラリの例外に基づき商務例外を呼び出し、処理要求と関連のロジックを持っているでしょう。

デフォルトでは、コンテナーは技術的な例外(EJBTransactionRolledbackException)に包み込み、予期しないものとみなされるEJBで発生するすべての例外をラップします。同様に、アプリケーション内の予期しない例外をすべてキャッチできます。例外ラッピングのほかに、コンテナは現在のトランザクションでロールバックをトリガします。
コンテナによる技術的な例外のラップを回避するには、ビジネス例外がコンテナによって予期しないものとみなされてはなりません。

  • どちらか、これらがチェックされます

    は広義には、次の2つのケースを持っています。この場合は何もしません。

  • どちらかは実行時です。 ApplicationExceptionアノテーションを追加するか、EJBのxml構成以降、アプリケーション例外動作を指定する必要があります。

    ApplicationExceptionのJavadocから

が アプリケーション例外であり、直接 (即ち、開封された)クライアントに報告されるべきであることを示すために例外を適用。

最後に、ロールバック操作が望ましいかどうかです。あなたはそのように設定することがあります。

@ApplicationException(rollback=true) 
public class MyBusinessRuntimeException extends RuntimeException { 

またはWebLogicで

@ApplicationException(rollback=false) 
public class MyBusinessRuntimeException extends RuntimeException { 

が、私はまた、メソッドのシグネチャでは、これらの例外を宣言しなければならなかった覚えています。


コメントの更新:

しかし、最初に、私は例 ConstraintValueExceptionのためのサードパーティ製のlibにから例外をキャッチする必要があります。

あなたは2つの方法があります。問題が発生する可能性がある場合は明示的に例外を処理するか、横方向に例外を処理します。 ConstraintViolationExceptionを参照されると思います。
例外は固有のものであり、処理されるコンテキストを必要とするとき、それが発生した例外を処理

あなたが特定のシナリオでは、特定のサードパーティの例外に予想される場合は、あなたがしたいですそれをキャッチしてビジネス例外を返す場合は、直ちに第三者の例外をキャッチする必要があります。
最初に、例外処理の方法を理解したらすぐに例外をキャッチすることをお勧めします。
2番目の例外は、例外を次のレイヤーに移動させないため、例外としてEJBTransactionRolledbackException例外になります。
しかし、時には例外的なタイプが正当な理由でトランスバーサル方法で処理されることがあります。
この場合、その例外に対してトランスバーサル処理を使用できます。

  • 横取り扱い例外が処理されるように必要な情報が含まれています:

あなたは横断方法であなたの予想実行時例外を処理する場合は、JEEインターセプターを使用して、あなたのをスローするためにそれを引くこと自身のビジネス例外。
この場合、インターセプタ内で、キャッチされた例外の原因とカスタム例外の間のマッピングを定義する必要があります。あなたの必要性を実行するためのインターセプタの

例(それはすべてのシナリオ、単に名目シナリオを処理しません):

public class WrappingInBusinessExceptionInterceptor { 

    @AroundInvoke 
    public Object handleExceptions(final InvocationContext ctx) throws Exception { 

     try { 
      Object result = ctx.proceed(); 
      return result; 
     } 

     catch (Exception exception) { 
      // log the root exception 
       ... 
       Exception causeException = e.getCause(); 
       if (causeException !=null && 
        causeException.getClass()==ConstraintValueException.class){ 
        // throw your custom exception 
        String businessMsg = 
         retrieveBusinessMessageFrom(causeException); 
        throw new MyBusinessException(businessMsg); 
       } 
     }        

    } 
+0

これはソリューションの第2の部分です。しかし、まず、私は、既存のキー値で自分のデータベースに何かを追加するときに、例えばConstraintValueExceptionのようなサードパーティのlibから例外をキャッチする必要があります。私がキャッチすると、正しいメッセージでフロントエンドで処理するbusinnesExceptionがスローされます。 –

+0

答えを更新しました。 – davidxxx

+0

しかし、あなたは私のポイントが表示されません。私のコードは、@Statelessという注釈を付けてすべてのクラスにマークを付けて、EJBにするときにのみ機能します。したがって、残りのリクエストを受け取った後のコンテナは、おそらくデータをEJBクラスから外した後にトランザクションを開いて閉じます。たとえば、サーブレットでテストしました。サーブレットクラスではすべてうまく動くので、EJBではないサーブレットクラスにサービスEJBオブジェクトを挿入することができました。そこで、私は自分のRolledBackTransactionExceptionを捕まえることができました。 –

関連する問題