6.9. Java™ Persistence API でのデータソースの使用

トランザクション管理の観点から、データソースが Java™Persistence API(JPA) でどのように使用されるかを理解することが重要です。このセクションでは、JPA 仕様自体の詳細や、最もよく知られている JPA 実装である Hibernate の詳細については説明しません。代わりに、このセクションでは、JPA 永続ユニットをデータソースにポイントする方法を示します。

6.9.1. データソースの参照について

META-INF/persistence.xml 記述子 (JPA 2.1 仕様 8.2.1.5 jta-data-source, non-jta-data-sourceを参照) は、2 種類のデータソース参照を定義します。

  • <jta-data-source> - これは、JTA トランザクションで使用する JTA 対応データソースに対する JNDI 参照です。
  • <non-jta-data-source> - これは、JTA トランザクション外で使用する JTA 対応データソースに対する JNDI 参照です。このデータソースは通常、Hibernate がデータベーススキーマを自動作成するように設定する hibernate.hbm2ddl.auto プロパティーなどと、初期化フェーズでも使用されます。

これらの 2 つのデータソースは、javax.sql.DataSource または javax.sql.XADataSource とは関連性がありません。これは、JPA アプリケーションを開発する時によくある誤解です。両方の JNDI 名は JNDI でバインドされた javax.sql.DataSource サービスを参照する必要があります。

6.9.2. JNDI 名の参照

OSGi サービスを osgi.jndi.service.name プロパティーに登録すると、OSGi JNDI サービスで バインドされます。OSGi ランタイム (Fuse/Karaf など) では、JNDI は name → value ペアの単純なディクショナリーではありません。OSGi の JNDI 名を使用してオブジェクトを参照するには、サービスルックアップやその他の複雑な OSGi メカニズム (サービスフックなど) が必要です。

Fuse の新規インストールでは、以下のリストはデータソースが JNDI に登録される方法を示します。

karaf@root()> install -s mvn:mysql/mysql-connector-java/5.1.34
Bundle ID: 223
karaf@root()> install -s mvn:org.osgi/org.osgi.service.jdbc/1.0.0
Bundle ID: 224
karaf@root()> install -s mvn:org.ops4j.pax.jdbc/pax-jdbc-mysql/1.3.0
Bundle ID: 225
karaf@root()> install -s mvn:org.ops4j.pax.jdbc/pax-jdbc/1.3.0
Bundle ID: 226
karaf@root()> install -s mvn:org.ops4j.pax.jdbc/pax-jdbc-pool-common/1.3.0
Bundle ID: 227
karaf@root()> install -s mvn:org.ops4j.pax.jdbc/pax-jdbc-config/1.3.0
Bundle ID: 228

karaf@root()> config:edit --factory --alias mysql org.ops4j.datasource
karaf@root()> config:property-set osgi.jdbc.driver.name mysql
karaf@root()> config:property-set dataSourceName mysqlds
karaf@root()> config:property-set osgi.jndi.service.name jdbc/mysqlds
karaf@root()> config:property-set dataSourceType DataSource
karaf@root()> config:property-set jdbc.url jdbc:mysql://localhost:3306/reportdb
karaf@root()> config:property-set jdbc.user fuse
karaf@root()> config:property-set jdbc.password fuse
karaf@root()> config:property-set jdbc.useSSL false
karaf@root()> config:update

karaf@root()> feature:install jndi

karaf@root()> jndi:names
JNDI Name                 │ Class Name
──────────────────────────┼───────────────────────────────────────────────
osgi:service/jndi         │ org.apache.karaf.jndi.internal.JndiServiceImpl
osgi:service/jdbc/mysqlds │ com.mysql.jdbc.jdbc2.optional.MysqlDataSource

ご覧のとおり、データソースは osgi:service/jdbc/mysqlds JNDI 名で利用できます。

しかし、OSGi の JPA の場合は、完全な JNDI 名 を使用する必要があります。以下は、データソース参照を指定する META-INF/persistence.xml フラグメントの例です。

<jta-data-source>
    osgi:service/javax.sql.DataSource/(osgi.jndi.service.name=jdbc/mysqlds)
</jta-data-source>
<non-jta-data-source>
    osgi:service/javax.sql.DataSource/(osgi.jndi.service.name=jdbc/mysqlds)
</non-jta-data-source>

上記の設定がないと、以下のエラーが発生する可能性があります。

Persistence unit "pu-name" refers to a non OSGi service DataSource