4

@ApplicationException(inherited = true, rollback = true) の例外があるが、サブクラスをロールバックしないようにしたい場合。@ApplciationException(rollback = false) でサブクラスに注釈を付けることはできますか? それともうまくいきませんか?仕様は、私が見つけることができるとは言っていないようです。

4

2 に答える 2

6

EJB 3.1 仕様 (JSR 318) では、セクション 14.2.1 でこれについて説明しています。例があります:

In the following example :
@ApplicationException(rollback=true)
public class ExceptionA extends RuntimeException
public class ExceptionB extends ExceptionA
@ApplicationException(inherited=false, rollback=false)
public class ExceptionC extends ExceptionB
public class ExceptionD extends ExceptionC

ExceptionA is an application exception with transaction rollback.
ExceptionB is an application exception with transaction rollback.
ExceptionC is an application exception without transaction rollback.
ExceptionD is not an application exception.
于 2013-01-23T19:48:07.060 に答える
4

JSR 220は、このシナリオで何が起こるべきかを明示的に述べていません。application-exceptionデプロイメント記述子要素が特定の EJB のアノテーション付きの値をオーバーライドすることを指定します。

ApplicationException アノテーションが例外クラスに適用され、rollback 要素の値が true で指定されているか、例外の application-exception デプロイメント記述子要素が rollback 要素を true として指定していない限り、アプリケーション例外は自動的にトランザクションにロールバックのマークを付けません。application-exception デプロイメント記述子要素の rollback サブ要素を明示的に指定して、ApplicationException アノテーションによって指定またはデフォルト設定されたロールバック値をオーバーライドできます。

@TransactionAttributeこれは、アノテーションが他の Java EE コンポーネント ( など)でどのように機能するかを組み合わせると、サブクラスのアノテーションがその親のアノテーションをオーバーライド@ConcurrencyManagementすることを強く想定するようになります。@ApplicationException簡単なテストでこれが当てはまることを確認しました(不完全なコードが表示されています):

@ApplicationException(inherited = true, rollback = true)
public class MyBaseException extends RuntimeException {
    // Constructors
}

public class MySubException1 extends MyBaseException {
    // Constructors
}

@ApplicationException(rollback = false)
public class MySubException2 extends MyBaseException {
    // Constructors
}

@Stateless
@TransactionManagement(TransactionManagementType.CONTAINER)
@TransactionAttribute(TransactionAttributeType.REQUIRED)
@Path("/misc/exception")
@Produces(MediaType.APPLICATION_JSON)
public class ExceptionResourceImpl {
   @Inject
   private BaseDAO baseDAO;

   public ExceptionResourceImpl() {
      super();
   }

   @GET
   @Path("/app/{id}")
   public Response getApplicationException(@PathParam("id") final String id) {
      final PaymentTypeModel model = new PaymentTypeModel();
      model.setPayment("Key" + System.currentTimeMillis());

      if ("1".equals(id)) {
         baseDAO.create(model);
         throw new MySubException1(
               "Throwing sub exception 1, default annotation behaviour");
      } else if ("2".equals(id)) {
         baseDAO.create(model);
         throw new MySubException2(
               "Throwing sub exception 2, overrides annotation behaviour");
      } else {
         return Response.status(Status.BAD_REQUEST)
               .entity("Must supply id of 1 or 2").build();
      }
   }
}

結果:

  • /misc/exception/app/1 を要求すると、画面にエラーが表示され、データベースにレコードが保存されません。
  • /misc/exception/app/2 をリクエストすると、画面にエラーが表示されますが、レコードデータベースに保存されます。つまり、トランザクションをロールバックしないためのアノテーション オーバーライドが処理されましMySubException2た。

* 編集 *

JSR 318ApplicationExceptionでは、例を使用して、継承されたアノテーションの動作を明確にしています。

次の例では:

@ApplicationException(rollback=true) public class ExceptionA extends RuntimeException

パブリック クラス ExceptionB は ExceptionA を拡張します

@ApplicationException(inherited=false, rollback=false) public class ExceptionC extends ExceptionB

public class ExceptionD extends ExceptionC

ExceptionA は、トランザクション ロールバックを伴うアプリケーション例外です。ExceptionB は、トランザクション ロールバックを伴うアプリケーション例外です。ExceptionC は、トランザクション ロールバックのないアプリケーション例外です。ExceptionD はアプリケーション例外ではありません

これにより、私の元のステートメントとテストが確認されます。

于 2013-01-23T19:18:10.533 に答える