About

JTA

プロジェクト文書

Built by Maven

Abstract

JUnit CDI Extensions for JTA は,JavaSE で実行される CDI コンテナで Java Transaction API (JTA) を利用できるようにします.

テストクラスを含む任意の bean で javax.transaction.UserTransaction を DI して利用することが出来ます.

@RunWith(CDI.class)
public class XxxTest {
    @Inject
    UserTransaction ut;
    ...
}

JTA およびコネクションプールの実装には, Seasar2 の提供する S2JTA と S2DBCP を使用します.ただし,DI コンテナとしての Seasar2 (S2Container) は使用しません.

DataSource

JTA と連携するデータソースを利用するには, org.seasar.junitcdi.jta.datasource.AbstractDataSource のサブクラスを作成して javax.annotation.sql.DataSourceDefinition で接続情報を注釈します.

@DataSourceDefinition(
    name = "java:comp/env/jdbc/DefaultDataSource", 
    className = "org.h2.Driver", 
    url = "jdbc:h2:mem:default",
    user = "...",
    password = "...")
public class DefaultDataSource extends AbstractDataSource {
}

このデータソースは bean として DI することが可能です.

    @Inject
    DataSource ds;

あるいは, @Resource で DI することも,JNDI からルックアップすることも可能です. 詳細は JUnit CDI Extensions Core の JNDI を参照してください.

接続情報は以下のように指定します.

要素 説明
name データソースを JNDI に登録する名前です.
className JDBC ドライバのクラス名です.( DataSourceDefinition 本来の仕様では DataSource のクラス名を指定することになっていますが, このクラスでは JDBC ドライバのクラス名として解釈します)
url 接続 URL です.
name ユーザ名です.
password パスワードです.

複数のデータソースが必要な場合は org.seasar.junitcdi.jta.datasource.AbstractDataSource のサブクラスを複数作成します. デフォルトで使用されるデータソース (一つだけです) を除いたクラスには,qualifier を指定します.

次の例ではデフォルトでないデータソースを qualifier Hoge で注釈しています.

@Qualifier
@Target( { TYPE, FIELD, PARAMETER })
@Retention(RUNTIME)
public @interface Hoge {}

@Hoge
@DataSourceDefinition(...)
public class HogeDataSource extends AbstractDataSource {
}

このデータソースを使用する場所も同じ qualifier で注釈します.

    @Inject
    @Hoge
    DataSource ds;

データソースのスコープは ApplicationScoped であり,テストメソッドが終了してスコープが破棄される際に自動的にクローズされます.

Declarative Transaction

テストメソッドに org.seasar.junitcdi.jta.Transactional アノテーションを指定することにより,JTAトランザクションの下でテストメソッドを実行することができます.

@RunWith(CDI.class)
public class XxxTest {
    @Test
    @Transactional
    public void test() throws Exception {
        ...
    }
    ...
}

Transactional アノテーションをテストクラスに指定することも出来ますが,その場合はライフサイクルメソッドなども トランザクション制御の対象となります ( static メソッドや final メソッドは除きます). ライフサイクルメソッドなどのトランザクションは,テストメソッドのトランザクションとは別になります.

デフォルトでは,テストメソッドの実行が終了するとトランザクションはロールバックされます. テストメソッドが正常終了した場合にトランザクションをコミットするには Transactional アノテーションの commit 要素に true を指定します.

    @Test
    @Transactional(commit = true)
    public void test() throws Exception {
        ...
    }

Transactional アノテーションの commit 要素に true を指定した場合でも,テストメソッドが例外をスローするとトランザクションはロールバックされます.