これを行う最も簡単な方法は、CDI インターセプターを使用して例外をキャッチすることです。CDI インターセプターは次のように定義できます。
@InterceptorBinding
@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface TransactionDebugger {
}
CDI Interceptor を定義したら、Interceptor アノテーションが使用されるときに実行されるクラスを作成する必要があります。@AroundInvoke を定義して、注釈を付けるメソッド内のコードの前にコードが呼び出されるようにします。 invocationContext.proceed()
アノテーションを付けたメソッドを呼び出し、返された結果 (存在する場合) を返します。したがって、try, catch (Exception)
スローされたあらゆる種類の例外をキャッチするために、この呼び出しを囲むことができます。次に、ロガー (ここでは log4j を使用) を使用してこの例外をログに記録し、上流のコードにも通知されるように例外を再スローします。
例外を再スローすると、CMT (コンテナー管理トランザクション) を使用することもできます。最終的にコンテナーは例外をキャッチし、トランザクション RollbackException をスローします。ただし、これで UserTransactions を簡単に使用して、例外がキャッチされたときに再スローする代わりに手動でロールバックを実行することもできます。
@Interceptor
@TransactionDebugger
public class TransactionInterceptor {
private Logger logger = LogManager.getLogger();
@AroundInvoke
public Object runInTransaction(InvocationContext invocationContext) throws Exception {
Object result = null;
try {
result = invocationContext.proceed();
} catch (Exception e) {
logger.error("Error encountered during Transaction.", e);
throw e;
}
return result;
}
}
CDI では Interceptor がデフォルトで有効になっていないため、次に、beans.xml (通常は src/META-INF にあります) に新しい Interceptor を含める必要があります。これは、注釈が定義されているプロジェクトだけでなく、注釈が使用されているすべてのプロジェクトで行う必要があります。これは、CDI がプロジェクトごとにインターセプターを初期化するためです。
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
http://xmlns.jcp.org/xml/ns/javaee/beans_1_1.xsd"
version="1.1" bean-discovery-mode="all">
<interceptors>
<class>package.database.TransactionInterceptor</class>
</interceptors>
</beans>
最後に、新しい CDI Interceptor で呼び出すメソッドに注釈を付ける必要があります。ここでは、トランザクションを開始するために @Transactional でアノテーションを付け、トランザクション内で発生する例外をキャッチするために @TransactionDebugger でアノテーションを付けます。
@Transactional @TransactionDebugger
public void init() {
...
}
これにより、init() コードの実行中に発生したすべてのエラーがログに記録されるようになりました。ロギングの粒度は、try、catch を Exception から Interceptor 実装クラス TransactionInterceptor の Exception のサブクラスに変更することで変更できます。