この演習では、Java Persistence API(JPA)を使用してオブジェクト・リレーショナル・マッピングを実行する方法を学習します。この章の内容は次のとおりです。
この演習では、実用バージョンのOracle Database 10g Express Edition(OracleXEデータベース)をシステムにインストール済であると想定しています。データベースがない場合は、次の場所からダウンロードできます。
http://www.oracle.com/technology/software/products/database/xe/index.html
EJBテクノロジの主な強化点はJPAの追加です。これにより、エンティティ永続性モデルが簡略化され、Java SEの永続性などEJB 2.1テクノロジにはなかった機能が追加されます。
JPAでは、Javaオブジェクト(永続エンティティ)にリレーショナル・データをマップし、これらのオブジェクトに後でアクセスできるようにリレーショナル・データベースに格納し、エンティティの状態を、使用元のアプリケーションの終了後も存続させることができます。エンティティ永続性モデルを簡略化するほかに、JPAはオブジェクト・リレーショナル・マッピングの標準化も行います。
Coherenceクラスタ内でのデータの格納方法を決定するために、バッキング・マップが使用されます。デフォルトでは、Coherenceはメモリーベースのバッキング・マップを使用します。データを永続化するためのバッキング・マップ実装は複数あります。
この演習ではJPA実装を使用します。この実装では、Javaの世界からデータベースの世界へのオブジェクト・リレーショナル・マッピング(ORM)を備えているため、Coherenceの標準的なgetまたはputを使用したり、JPAおよびOracle TopLink(オープン・ソースEclipseLinkプロジェクトに基づく)を使用してCoherenceコールをデータベース・コールに変換できます。
この演習では、Jdeveloperを使用して次の手順を実行します。
OracleXEデータベースでHR
スキーマへの接続を作成します。
EMPLOYEES
表向けのJPAオブジェクトを自動生成します。
インストール済のOracleXEデータベースでHR
アカウントをロック解除します。
ここでは、使用するマシンにOracleXEデータベースをインストール済で、HRスキーマにアクセスできると想定しています。HRアカウントをロック解除するには、次の手順を実行します。
「スタート」→「すべてのプログラム」→「Oracle Database 10g Express Edition」→「SQLコマンドラインの実行」に移動します。
connect system as sysdba
と入力し、パスワードを要求されたらwelcome1
と入力します(注意: この演習では、ユーザー名はsystem
、パスワードはwelcome1
としています)。
次のコマンドを入力してアカウントをロック解除します。
alter user hr identified by hr account unlock;
JDeveloperで、JPA
という新規プロジェクトを作成します。詳細は、「既存アプリケーションでの新規プロジェクトの作成」を参照してください。
「プロジェクト・プロパティ」の「実行/デバッグ/プロファイル」にあるデフォルトの「Javaオプション」で適切なログ・レベルを設定し、ローカル記憶域を無効にします。
-Dtangosol.coherence.distributed.localstorage=false -Dtangosol.coherence.log.level=3
クラスパスがcoherence.jar
ファイルのフルパスを指していることを確認します。
C:\oracle\product\coherence\lib\coherence.jar
次の手順に従い、HRデータベース・スキーマに接続してJPA永続性ユニットを作成します。
ナビゲータの「アプリケーション・リソース」セクションで「接続」を右クリックし、「接続の作成」→「データベース接続」を選択します。
HRスキーマに接続するための詳細を入力して「OK」をクリックします。
接続名: XE_HR
接続タイプ: Oracle (JDBC)
ユーザー名: hr
パスワード: hr
「接続のテスト」をクリックします。
これで「Success
!」と表示されます。
「OK」をクリックします。
次の手順に従い、JPA永続性ユニットおよびエンティティBeanを作成します。
JPA
プロジェクトを右クリックし、「新規」を選択します。「ビジネス層」で「EJB」を選択して、「表からのエンティティ」を選択します。「OK」をクリックします。
「エンティティ作成(表ベース)」ウィンドウで、「EJB 3.0 -- JPAエンティティ」を選択して「次へ」をクリックします。
「新規」をクリックし、永続性ユニットを作成します(各永続性ユニットは、永続化の際に、一連のクラスおよびそのマッピング特性を定義します)。次の詳細を入力して「OK」をクリックします。
名前: JPA
JTAデータソース名: <空白のまま>
非JTAデータソース名: <空白のまま>
データベース・プラットフォーム: Oracle
サーバー・プラットフォーム: なし
「OK」をクリックします。「エンティティ作成(表ベース)」画面に戻ったら、「次へ」をクリックします。
「オンライン・データベース接続」オプションを選択し、「次へ」をクリックします。
「データベース接続の詳細」ウィンドウで、「次へ」をクリックします。
「問合せ」ボタンをクリックして、図8-9に示す表を表示します。EMPLOYEES
表を選択し、これを「選択」列に移動します。「次へ」をクリックします。
デフォルトの「一般オプション」を受け入れて「次へ」をクリックします。
デフォルトの「エンティティの詳細を指定」を受け入れて「次へ」をクリックします。
「サマリー」ページが表示されます。「終了」をクリックしてエンティティBeanを作成します。ナビゲータのEJBログ・ウィンドウに、図8-12のようなメッセージが表示されます。
persistence.xml
の内容を、例8-1に示すコードに置き換えて、ファイルを保存します。接続の詳細がデータベース接続の詳細と一致していることを確認します。c:\home\oracle\labs\JPA\src\META-INF
フォルダにpersistence.xml
ファイルが表示されます。
例8-1 persistance.xmlファイルの内容
<persistence xmlns:xsi="http://www.w3.org/2001/XMLSchemainstance" version="1.0" xmlns="http://java.sun.com/xml/ns/persistence">
<persistence-unit name="JPA" transaction-type="RESOURCE_LOCAL">
<provider>
org.eclipse.persistence.jpa.PersistenceProvider
</provider>
<class>com.oracle.handson.Employees</class>
<properties>
<property name="javax.persistence.jdbc.driver" value="oracle.jdbc.OracleDriver"/>
<property name="javax.persistence.jdbc.url" value="jdbc:oracle:thin:@localhost:1521:XE"
/>
<property name="javax.persistence.jdbc.password" value="hr"/>
<property name="javax.persistence.jdbc.user" value="hr"/>
</properties>
</persistence-unit>
</persistence>
テキスト・エディタを開いて、jpa-cache-config.xml
というファイルを作成します。例8-2に示すコードを使用します。このファイルをhome\oracle\labs\
ディレクトリに保存します。
例8-2 JPA用キャッシュ構成
<?xml version="1.0" encoding="windows-1252" ?> <cache-config> <caching-scheme-mapping> <cache-mapping> <!-- Set the name of the cache to be the entity name --> <cache-name>Employees</cache-name> <!-- Configure this cache to use the scheme defined below --> <scheme-name>jpa-distributed</scheme-name> </cache-mapping> </caching-scheme-mapping> <caching-schemes> <distributed-scheme> <scheme-name>jpa-distributed</scheme-name> <service-name>JpaDistributedCache</service-name> <backing-map-scheme> <read-write-backing-map-scheme> <!-- Define the cache scheme --> <internal-cache-scheme> <local-scheme/> </internal-cache-scheme> <cachestore-scheme> <class-scheme> <class-name>com.tangosol.coherence.jpa.JpaCacheStore</class-name> <init-params> <!-- This param is the entity name This param is the fully qualified entity class This param should match the value of the persistence unit name in persistence.xml --> <init-param> <param-type>java.lang.String</param-type> <param-value>{cache-name}</param-value> </init-param> <init-param> <param-type>java.lang.String</param-type> <param-value>com.oracle.handson.{cache-name}</param-value> </init-param> <init-param> <param-type>java.lang.String</param-type> <param-value>JPA</param-value> </init-param> </init-params> </class-scheme> </cachestore-scheme> </read-write-backing-map-scheme> </backing-map-scheme> <autostart>true</autostart> </distributed-scheme> </caching-schemes> </cache-config>
JPAプロジェクトのキャッシュ・サーバー・ファイルを作成します。cache-server.cmd
ファイルを使用して作成を開始できます。
ターミナル・ウィンドウを開きます。/oracle/product/coherence/bin
ディレクトリに移動し、cache-server.cmd
ファイルをjpa-cache-server.cmd
にコピーします。
cp cache-server.cmd jpa-cache-server.cmd
jpa-cache-server.cmd
を編集します。Java_OPTS
に、キャッシュ構成ファイルを宣言します。
-Dtangosol.coherence.cacheconfig=C:\home\oracle\labs\jpa-cache-config.xml
-cp
引数に次のCLASSPATH
を追加します。C:\home\oracle\labs\JPA\classes
C:\home\oracle\labs\JPA\classes
さらに、CLASSPATH
に次のJARファイルを追加する必要があります。
Coherence JPAライブラリ: C:\oracle\product\coherence\lib\coherence-jpa.jar
EclipseLink永続性ライブラリ: C:\oracle\product\modules\org.eclipse.persistence_1.0.0.0_2-0.jar
Oracle JDBC JAR ojdbc6.jar
(データベース接続用): C:\oracle\product\wlserver_10.3\server\lib\ojdbc6.jar
Coherence TopLinkライブラリ: C:\oracle\product\coherence\lib\coherence-toplink.jar
javax.persistence.*
ライブラリ: C:\oracle\product\modules\javax.persistence_1.0.0.0_1-0-2.jar
このクラスパスは次のようになります。
... C:\oracle\product\coherence\lib\coherence-jpa.jar;C:\oracle\product\modules\org.eclipse.persistence_1.0.0.0_2-0.jar;C:\oracle\product\wlserver_10.3\server\lib\ojdbc6.jar;C:\oracle\product\modules\javax.persistence_1.0.0.0_1-0-2.jar" ...
例8-3に、変更後のjpa-cache-server.cmd
ファイルを示します。
例8-3 変更後のjpa-cache-server.cmdファイル
@echo off @ @rem This will start a cache server @ setlocal :config @rem specify the Coherence installation directory set coherence_home=c:\oracle\product\coherence @rem specify the JVM heap size set memory=512m :start if not exist "%coherence_home%\lib\coherence.jar" goto instructions if "%java_home%"=="" (set java_exec=java) else (set java_exec=%java_home%\bin\java) :launch set java_opts="-Xms%memory% -Xmx%memory% -Dtangosol.coherence.cacheconfig=\home\oracle\labs\jpa-cache-config.xml" "%java_exec%" -server -showversion "%java_opts%" -cp "%coherence_home%\lib\coherence.jar;C:\home\oracle\labs\JPA\classes;C:\oracle\product\coherence\lib\coherence-jpa.jar;C:\oracle\product\modules\org.eclipse.persistence_1.0.0.0_2-0.jar;C:\oracle\product\wlserver_10.3\server\lib\ojdbc6.jar;C:\oracle\product\oracle_common\modules\oracle.toplink_11.1.1\eclipselink-dbwsutils.jar;C:\oracle\product\modules\javax.persistence_1.0.0.0_1-0-2.jar" com.tangosol.net.DefaultCacheServer %1 goto exit :instructions echo Usage: echo ^<coherence_home^>\bin\cache-server.cmd goto exit :exit endlocal @echo on
jpa-cache-server.cmd
ファイルを保存し、他のキャッシュ・サーバーがすべて停止していることを確認して、jpa-cache-server.cmd
を実行します。
C:\oracle\product\coherence\bin>jpa-cache-server.cmd
次の手順に従って、JDeveloperでランタイム・プロパティを変更し、クラスパスを編集します。
JPA
の「プロジェクト・プロパティ」を編集して「実行/デバッグ/プロファイル」構成を変更します。既存の「Javaオプション」に次の行を追加します。
-Dtangosol.coherence.cacheconfig=C:\home\oracle\labs\jpa-cache-config.xml
既存のプロジェクト・プロパティにCLASSPATH
エントリを追加します。
「ツール」→「プロジェクト・プロパティ」→「ライブラリとクラスパス」に移動します。「JAR/ディレクトリの追加」ボタンおよび「ライブラリの追加」ボタンを使用して、まだCLASSPATH
に存在しない次のJARファイルおよびライブラリを追加します(注意: coherence.jar
ファイルがすでに存在している必要があります)。
JpaCacheStore
への参照を示すcoherence-jpa.jar
TopLink
の事前定義されたJDeveloperライブラリ。必要なEclipseLinkのJARおよびAPIを提供します。
EcilpseLink Persistence JARファイル(Eclipse永続性API用): C:\oracle\product\modules\org.eclipse.persistence_1.0.0.0_2-0.jar
Oracle JDBC
の事前定義されたJDeveloperライブラリ(データベース接続用)
Oracle XML Parser v2
の事前定義されたJDeveloperライブラリ(XML解釈用)
Java Persistence JARファイル(永続性API用): C:\oracle\product\modules\javax.persistence_1.0.0.0_1-0-2.jar
Java EE 1.5 API。デフォルトで含まれています。
「ライブラリとクラスパス」画面は、図8-13のようになります。
JPA
プロジェクトにEmployee
オブジェクトと相互作用する新しいクラスを作成します。
main
メソッドを含むRunEmployeeExample
という新しいクラスを作成します。詳細は、「Javaクラスの作成」を参照してください。
次の処理を実行するコードを作成します。
EMPLOYEE_ID
を使用して従業員を取得。EMPLOYEE_ID
のデータ型はlong
である必要があります。
給与を表示。
従業員に10%の昇給。
値を再取得して昇給を確認。
例8-4に、可能な解決策を示します。
例8-4 Employeeクラス・ファイルのサンプル
package com.oracle.handson; import com.tangosol.net.CacheFactory; import com.tangosol.net.NamedCache; public class RunEmployeeExample { public RunEmployeeExample() { } public static void main(String[] args) { long empId = 190L; // emp 190 - Timothy Gates NamedCache employees = CacheFactory.getCache("Employees"); Employees emp = (Employees)employees.get(empId); System.out.println("Employee " + emp.getFirstName() + " " + emp.getLastName() + ", salary = $" + emp.getSalary() ); // give them a 10% pay rise emp.setSalary( emp.getSalary() * 1.1); employees.put(empId, emp); Employees emp2 = (Employees)employees.get(empId); System.out.println("New Employee details are " + emp2.getFirstName() + " " + emp2.getLastName() + ", salary = $" + emp2.getSalary() ); } }
これで、JPAを使用してデータベースに永続化するという注釈がEmployees
クラスに付けられ、データベースの場所をJPAに知らせるpersistence.xml
ファイルを含めたため、Coherenceでは、JPAを使用するCacheStore
実装を採用して、オブジェクトをデータベースにロードおよび格納します。get(Object key)
メソッドを使用すると、次の事象が発生します。
Coherenceで、このキーを含むエントリが検索されます。
このエントリがまだキャッシュされていない場合や、期限切れでキャッシュから削除されている場合、Coherenceではバッキング・マップが要求され、JPAとEclipseLinkを使用してデータが取得されます。
このエントリがキャッシュ内にある場合、Coherenceでは、EclipseLinkを経由しないでアプリケーションにエントリが直接返されます。put(Object Key,Object Value)
を使用すると、Coherenceでは、EclipseLink経由でJPAが使用され、変更内容がデータベースに永続化されます。
プロジェクト・ファイルがまだコンパイルされていない場合は、これらをコンパイルします。
RunEmployeeExample.java
を実行します。
この出力は図8-14のテキストのようになります。