|
| Home > Apache Geronimo v2.0 - JA > Documentation > 4. Apache Geronimo への移行 > 4.6. JBoss to Geronimo - Hibernate の移行 |
この文章は、Hibernate 3.2 を ORM ツールとして利用するアプリケーションを JBoss アプリケーション・サーバー 4.2.1 から Apache Geronimo 2.0 へ移行する手助けとなります。
Hibernate は強力な、高性能なオブジェクト・リレーショナルの永続化とクエリー・サービスです。データベースのフィールドに結びつけられた属性の getter と setter メソッド持つ永続化(POJO)クラスの開発の助けになります。関連・継承・ポリモーフィズム・コンポジション・コレ クションなどのオブジェクト指向の特徴に従うことになります。Hibernate は、ネイティブな SQL、オブジェクト指向検索条件、例示 API などと同じように、移行可能な SQL 表現(HQL)を用いて検索を表現できます。
基本的には、Hibernate は Java クラスとデータベースの表を結びつけます。また、データ検索や検索機構によって、開発時間の短縮につながります。自然と、Java 中間層におけるオブジェクト指向のコード開発ができます。Hibernate のユニークな特徴は、MySQL、Oracle または DB2 など、どのようなデータベースにもアプリケーションが切り替えることができる透過的永続化機構です。Hibernate は Java Swing アプリケーション、Java サーブレット・アプリケーション、または EJB セッション・ビーンを利用するJ2EE アプリケーションなどに利用できます。(今回は、Java サーブレット・アプリケーションを利用します)
移行の手順を明らかにするために、最初にサンプル・アプリケーションを JBoss にデプロイし、その後 Geronimo へ移行します。サンプル・アプリケーションは、オンライン取引アプリケーションです。JDBC の移行手順の説明で既に利用した物です。このアプリケーションでは永続化のために Hibernate を利用するように変更します。
この文章には以下のセクションがあります。
Hibernate は以下のサービスを提供します。
また、とても柔軟であり、さまざまなサービスと組み合わせて利用できます。JBoss、Geronimo ともトランザクション管理とコネクション管理機能を持っているので、この文章では hibernate を O/R マッピング機能のみ利用できるように構成します。一般的に、Hibernate はアプリケーション・サーバーと一緒に利用するように構成します。Hibernate はコネクション・プールの生成と環境の設定に構成ファイルである hibernate.cfg.xml を必要とします。このファイルにはデータベース・ドライバー、接続 url、SQL 方言(これは利用している RDBMS の仕様)、ユーザー名、パスワード、プールの大きさなどのパラメーターを含みます。また、*.hbm.xml というマッピング用ファイルの場所の定義も含みます。マッピング用ファイルはデータベースの表のフィールドと永続化クラスの属性とを結びつけるものです。
これらのプロパティは Apache Geronimo v2.0 を含めたアプリケーション・サーバーで一般的なものです。
しかし、JBoss(さらに言えば、Hibernate MBean)は、2つのさらなるデプロイメント機構を持っています。
一つ目は Hibernate アーカイブ(HAR ファイル)です。これは Hibernate のすべてのクラスとマッピング・ファイルが含まれる特別なアーカイブである HAR ファイルです。JBoss はこのアーカイブを EAR や WAR ファイルと同じ方法でデプロイします。
もうひとつは、他のアプリケーションのクラスといっしょに、Hibernate のすべてのクラスとマッピング・ファイルを、例えば EAR の中に単にいれることです。Hibernate MBean は個別に構成され、マッピング・ファイルがアプリケーションのすべての JAR を探しかたを指定します。両方のデプロイメント機構とも、手作業で構成することなく、通常必要となるような設定コードを記述することなく、Hibernate オブジェクトをアプリケーションに追加することができます。
構造的には、HAR ファイルは JBoss サービス・アーカイブ(SAR ファイル)に似ています。HAR ファイルは Hibernate クラス・ファイルとマッピング・ファイル(*.hbm.xml)を、Hibernate アプリケーションが生成する必要がある Hibernate MBean の構成の定義を持つ標準の jboss-service.xml ファイルと一緒に保持します。最新の JBoss 製品では、hibernate-service.xml という名前にリネームされていますが、同じ構造と目的を持っています。
Hibernate アーカイブはトップレベルのパッケージとして、または EAR ファイルのコンポーネントとしてデプロイすることができます。Hbernate アーカイブは標準の J2EE デプロイメントの形式ではないので、これらをコンテキスト内で利用できるように EAR ファイルに jboss-app.xml ファイルを記述する必要があります。
以下の表はこれらアプリケーション・サーバーの機能ごとの比較です。
| Feature | Apache Geronimo v2.0 | JBoss v4.2.1 |
|---|---|---|
| コンテナー管理データソース | サポートされています。Hibernate は与えられた JNDI 名のデータソースを利用することができます。アプリケーションと同じスレッドで実行されるからです。 |
サポートされています。Hibernate は与えられた JNDI 名のデータソースを利用することができます。 |
| JNDI 自動バインディング | サポートされていません。 | サポートされています。プロパティが設定されるとセッション・ファクトリーが JNDI コンテキストに結びつけられます。 |
| JTA セッション・バインディング | この機能は導入直後そのままの状態ではサポートされていません。Geronimo トランザクション・マネージャーが利用できるようにルックアップを記述する必要があります。 |
導入直後からサポートされています。Hibernate は JBoss トランザクション・マネージャー向けのルックアップ・クラスを持っています。 |
| JMX デプロイメント | 導入直後そのままの状態ではサポートされていません。GBean と Hibernate コネクション・プロバイダー・クラスを記述すれば実装できます。 |
サポートされています。Hibernate は JBoss にデプロイできる org.hibernate.jmx.HibernateService を持っています。 |
| Hibernate アーカイブ (HAR) | サポートされていません。Hibernate クラスは J2EE アーカイブの一部としてデプロイされます。 | サポートされています。HAR は構成とマッピング・ファイルが含まれ、他のサーバーへのデプロイをサポートできるようになります。 |
| キャッシング | hibernate のキャッシング機構を利用できます。 | hibernate のキャッシング機構を利用できます。JBoss キャッシュもサポートされています。 |
| セッション管理 |
サポートされていません。手動でセッションを開く必要があります。 | Hibernate セッション・ライフサイクルは自動的に JTA トランザクションのスコープに結びつけることができます。手動でセッションを開いたり閉じたりする必要がなく、これは JBoss EBJ インターセプターが行います。 |
| Hibernate マッピング・ファイル | Hibernate マッピング・ファイルの場所を指定する必要があります。 | HAR デプロイを利用する場合は JBoss は自動的に Hibernate マッピング・ファイルを探しだします。 |
この文章には、JBoss から Geronimo へアプリケーションの移行をデモンストレーションするサンプル・アプリケーションがあります。名前は Online Brokerage
です。オンライン取引でユーザーが株の売買を行うシナリオです。このアプリケーションには以下の5つのページがあります。
以下の図は、アプリケーションのフローです。

オンライン取引サンプル・アプリケーションには、以下のパッケージが含まれます。
オンライン取引には、以下の JSP ページを含みます。
オンライン取引アプリケーションの開発とビルドのツールは以下の通りです。
Ant はピュア Java のビルド・ツールです。war ファイルをビルドし、オンライン取引アプリケーション向けデータベースを作成するために利用されています。Ant は以下の URL からダウンロードできます。
この文章を書いている時点では Hibernate 3.2 が最新の利用可能バージョンです。以下の URL からダウンロードできます。
http://www.hibernate.org![]()
Hibernate に関する他の文章は、以下の URL にあります。
http://hibernate.org/5.html![]()
http://www.hibernate.org/hib_docs/v3/reference/en/html/tutorial.html![]()
Hibernate をダウンロードし、インストールしてください。インストールしたディレクトリーを後ほど <hibernate_home> として参照します。
このアプリケーションのデモンストレーションに利用するデータベースは MySQL です。サンプル・データベース名は adi です。STOCKS、USERS、USERSTOCKS の3つのテーブルも持ちます。各テーブルは以下のフィールドを持ちます。
| Table Name | Fields |
|---|---|
| STOCKS | ID (PRIMARY KEY) NAME PRICE |
| USERS | USERID (PRIMARY KEY) NAME PASSWORD ADDRESS CASH |
| USERSTOCKS | ID (PRIMARY KEY) USERID (PRIMARY KEY) NAME PRICE QUANTITY |
USERSTOCKS テーブルは、各ユーザが所有する株を保存するために利用されます。USER と STOCKS テーブルはユーザーと株の詳細情報を保存するために利用されます。これは単にサンプル・アプリケーションですので、ユーザーの持つ金額の量は、ユーザー登 録時にユーザー自身に入力してもらいます。
このデータベース生成用の DDL は db.sql です。<brokerage_homge>\sql ディレクトリーにあります。
このセクションでは、サンプルの JBoss 環境がどのように、どこにインストールされるかを示すので、貴方はこのシナリオを貴方の実装に合わせることができます。
JBoss のインストール、構成と管理の詳細な説明については、JBoss のドキュメントにあります。JBoss のウェブ・サイトで最新のドキュメントをチェックしてください。
以下のリストはインストールと初期環境の構成を完了させ、サンプル・アプリケーションのデプロイの準備を完了させるまでに必要な一般的なタスクを示します。
この文章でのオンライン取引アプリケーションのビルドと実行のために、ビルド・ツールとアプリケーションが利用するデータベースをインストールし、構成する必要があります。
前述のとおり、このアプリケーションは MySQL データベースを利用しています。次の URL からダウンロードできます。
メモ:貴方の持つ MySQL のバージョンに応じて、MySQL Connector/J のふさわしいバージョン (3.1、5.0、5.1) もダウンロードしてください。
この MySQL コネクターは <JBOSS_HOME>/server/default/lib に置いてください。
MySQL のインストールと構成は、かなり直感的です。MySQL リファレンス・マニュアルは次の URL からダウンロードできます。
http://dev.mysql.com/doc/mysql/en![]()
メモ:簡単に構成するために、私はセキュリティ設定を変更し、root ユーザーに "password" というパスワードをつけました。このユーザー ID とパスワードは後ほどサンプル・アプリケーションからデータベースへ接続する際に利用されます。
MySQL のインスタンスが構成されたら、書庫アプリケーション(訳注:オンライン取引アプリケーションの間違い?)が利用するサンプル・データベースを作ります。コマンド・ラインから以下のコマンドを入力し、MySQL モニターを始動してください。
mysql -u root -ppassword
-p フラグとパスワードとの間にブランク文字がないことに注意してください。
MySQL コマンド・インターフェースが起動すると、以下のような表示になります。
Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 7 to server version: 4.1.14-nt Type 'help;' or '\h' for help. Type '\c' to clear the buffer. mysql>
MySQL コマンド・インターフェースから、以下のコマンドを入力し、adi サンプル・データベースを作成してください。
mysql> create database adi;
前述のとおり、オンライン取引アプリケーションのビルドには Apache Ant を利用しています。もしまだ Ant をインストールしていなかったら、そろそろインストールして、 <ant_home>\bin ディレクトリーをシステムの path 変数に追加してください。
Apache Ant は以下の URL からダウンロードできます。
JBoss には Hibernate が同梱されていますので、hibernate とは別に jar をダウンロードする必要はありません。
この文章でのオンライン取引アプリケーションには、アプリケーションのビルドとデータベースの生成に利用できる Ant スクリプトが含まれています。サンプル・アプリケーションを次の URL からダウンロードしてください。Online Brokerage![]()
zip ファイルを解凍すると、brokerage ディレクトリーが作られます。以下、このディレクトリーを <brokerage_home> とします。このディレクトリーで build.properties ファイルを開き、環境に合わせてプロパティを編集してください。以下に例を示します。
#Replace java.home with your jdk directory java.home=<java_home> #Replace jboss.home with the parent directory of lib/j2ee.jar jboss.home=<jboss_home>/server/<your_server_name> #Replace geronimo.home with the geronimo home directory. geronimo.home=<geronimo_home> #Fully qualified name of the JDBC driver class db.driver=com.mysql.jdbc.Driver #database url db.url=jdbc:mysql://localhost:3306/adi #database userId db.userid=root #database password db.password=password #script file for creating the tables sql.file=sql/db.sql #location of the jdbc driver jar. driver.classpath=<mysql-connector_home>/mysql-connector-java-3.1.14-bin.jar #location of the hibernate jars. dependency.dir=<hibernate_home>/lib
Hibernate の jar ファイルのパスが dependency.dir タグで定義されています。Geronimo と JBoss がそれぞれに Hibernate のコピーを持つ必要があることに注意してください。このディレクトリーに、<hibernage_home> ディレクトリーにある hibernate3.jar ファイルをコピーする必要があります。
| 重要: build.properties ファイルの driver.classpath を設定する際に、スラッシュ "/" を利用することに注意してください。そうしないとコンパイル・エラーになります。 |
コマンド・プロンプトやシェルで、<brokerage_home> ディレクトリーに移動して、ant コマンドを実行してください。そうすると、<brokerage_home>\jboss-artefact ディレクトリーに war 、har 、ear ファイルをビルドします。ant によってビルドされた war は、JBoss 固有のデプロイメント・ディスクリプターである jboss-web.xml ファイルを WEB-INF ディレクトリーに含みます。HAR ファイルには JBoss 固有の hibernate-service.xml ファイルを META-INF ディレクトリーに含みます。EAR ファイルには JBoss 固有のデプロイメント・ディスクリプターである jboss-app.xml を含みます。これらのファイルについて、以下に例を示します。
<?xml version="1.0" encoding="UTF-8"?> <jboss-web> <context-root>/brokerage</context-root> <resource-ref> <res-ref-name>jdbc/HibernateDB</res-ref-name> <res-type>javax.sql.DataSource</res-type> <jndi-name>jdbc/HibernateDS</jndi-name> </resource-ref> </jboss-web>
resource-ref 要素は、web.xml ファイルにある jdbc/HibernateDB という名前で参照されているリソースと、今回の例での MySQL データ・ソース向けである java:jdbc/HibernateDS という JNDI 名のリソースとを結び付けるために利用されます。
<?xml version="1.0" encoding="UTF-8"?> <server> <mbean code="org.jboss.hibernate.jmx.Hibernate" name="jboss.har:service=Hibernate"> <attribute name="DatasourceName">java:jdbc/HibernateDS</attribute> <attribute name="Dialect"> org.hibernate.dialect.MySQLDialect </attribute> <attribute name="SessionFactoryName"> java:/hibernate/BrokerageSessionFactory </attribute> <attribute name="CacheProviderClass"> org.hibernate.cache.HashtableCacheProvider </attribute> <!-- <attribute name="ScanForMappingsEnabled">true</attribute> --> <attribute name="ShowSqlEnabled">true</attribute> </mbean> </server>
このファイルには設定する必要のある hibernate のプロパティを含んでいます。これらの名称と機能は次のとおりです。
hibernate-service.xml ファイルは EAR(訳注:原文は EAR ですが、HAR では?)の META-INF ディレクトリーの中にあります。
<!DOCTYPE jboss-app PUBLIC "-//JBoss//DTD J2EE Application 1.4//EN" "http://www.jboss.org/j2ee/dtd/jboss-app_4_0.dtd"> <jboss-app> <module> <har>brokerage.har</har> </module> </jboss-app>
jboss-app.xml ファイルは EAR ファイルの META-INF ディレクトリーの中にあり、har ファイルの名前を記述しています。
以下の例ではこのアプリケーションで利用しているデプロイメント記述である web.xml を示します。web.xml ファイルは brokerage.war ファイルの WEB-INF ディレクトリーにあるデプロイメント記述で、サーブレット名やアプリケーションのデフォルトの JSP などについて記述されています。
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns="http://java.sun.com/xml/ns/j2ee" version="2.4" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"> <display-name>brokerage</display-name> <servlet> <display-name>Trade-Dispatcher</display-name> <servlet-name>TradeDispatcher</servlet-name> <servlet-class>com.dev.trade.servlet.TradeDispatcherServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>TradeDispatcher</servlet-name> <url-pattern>/login</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>TradeDispatcher</servlet-name> <url-pattern>/stocks</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>TradeDispatcher</servlet-name> <url-pattern>/userstocks</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>TradeDispatcher</servlet-name> <url-pattern>/buy</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>TradeDispatcher</servlet-name> <url-pattern>/sell</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>TradeDispatcher</servlet-name> <url-pattern>/register</url-pattern> </servlet-mapping> <welcome-file-list> <welcome-file>/login.jsp</welcome-file> </welcome-file-list> <error-page> <exception-type>javax.servlet.ServletException</exception-type> <location>/error.jsp</location> </error-page> <resource-ref> <res-ref-name>jdbc/HibernateDB</res-ref-name> <res-type>javax.sql.DataSource</res-type> <res-auth>Container</res-auth> <res-sharing-scope>Shareable</res-sharing-scope> </resource-ref> </web-app>
前述のとおり、db.sql スクリプトがサンプル・データを生成します。このファイルの場所はすでに build.properties 内で sql.file タグによって定義されています。サンプル・データの生成には、単に <brokerage_home> ディレクトリーで以下のコマンドを実行してください。
ant populateDB
サンプル・アプリケーションをデプロイする前に、このアプリケーションが必要とするデータ・ソースを構成する必要があります。JBoss でデータ・ソースの構成をデプロイするには、<brokerage_home>\plan ディレクトリーにある mysql-ds.xml ファイルを以下のディレクトリーにコピーしてください。
<jboss_home>\server\<your_server_name>\deploy
データベースのデプロイと同様に、JBoss でのオンライン取引アプリケーションのデプロイは、Ant でビルドした brokerage.ear ファイルを以下のディレクトリーにコピーしてください。
<jboss_home>\server\<your_server_name>\deploy
もし JBoss がすでに始動していたら、自動的にアプリケーションがデプロイされ、始動されます。そうでなければ、アプリケーションは次回始動時にデプロイされ、始動されます。
アプリケーションをテストするには、ウェブ・ブラウザーを開き、以下の URL に接続してください。
http://localhost:8080/brokerage![]()
オンライン取引アプリケーションのログイン画面が表示されます。user name 欄に j2ee 、password 欄に password を入力し、login をクリックしてください。以下の図のような available stocks ページが表示されます。アプリケーションは構成され、実行されています。

以下の URL から Geronimo をダウンロードし、インストールしてください。
http://geronimo.apache.org/downloads.html![]()
そこにあるリリース・ノートには、システム要件とインストール、始動方法がが明示されています。以下、この文章では Geronimo のインストール・ディレクトリーを <geronimo_home> とします。
Geronimo でオンライン取引アプリケーションを実行するために、JBoss で利用したものと同じ MySQL データベース を利用します。Geronimo 環境に準備のためにするべき作業は、データ・ソースを構成するだけです。
データ・ソースのデプロイメント・プランで参照可能になるように、MySQL データベースのドライバーを Geronimo リポジトリーにコピーする必要があります。Geronimo リポジトリーは <geronimo_home>/repository ディレクトリにあります。このディレクトリーの中に mysql/jars というディレクトリーを作り、そこへ mysql-connector-java-3.1.14-bin.jar ファイルをコピーしてください。
データ・ソースのデプロイメント・プランを定義する必要があります。簡単になるように、サンプル・アプリケーションにはすでに mysql-geronimo-plan.xml というデプロイメント・プランが <brokerage_home>\plan ディレクトリーの中にあります。以下の例がデプロイメント・プランの中身です。
<?xml version="1.0" encoding="UTF-8"?> <connector xmlns="http://geronimo.apache.org/xml/ns/j2ee/connector-1.2"> <dep:environment xmlns:dep="http://geronimo.apache.org/xml/ns/deployment-1.1"> <dep:moduleId> <dep:groupId>user</dep:groupId> <dep:artifactId>database-pool-HibernateDB</dep:artifactId> <dep:version>2.0</dep:version> <dep:type>car</dep:type> </dep:moduleId> <dep:dependencies> <dep:dependency> <dep:groupId>mysql</dep:groupId> <dep:artifactId>mysql-connector-java</dep:artifactId> <dep:version>3.1.14-bin</dep:version> <dep:type>jar</dep:type> </dep:dependency> </dep:dependencies> </dep:environment> <resourceadapter> <outbound-resourceadapter> <connection-definition> <connectionfactory-interface>javax.sql.DataSource</connectionfactory-interface> <connectiondefinition-instance> <name>HibernateDS</name> <config-property-setting name="Password">password</config-property-setting> <config-property-setting name="CommitBeforeAutocommit">false</config-property-setting> <config-property-setting name="Driver">com.mysql.jdbc.Driver</config-property-setting> <config-property-setting name="ExceptionSorterClass">org.tranql.connector.AllExceptionsAreFatalSorter</config-property-setting> <config-property-setting name="UserName">root</config-property-setting> <config-property-setting name="ConnectionURL">jdbc:mysql://localhost:3306/adi</config-property-setting> <connectionmanager> <local-transaction/> <single-pool> <max-size>10</max-size> <min-size>0</min-size> <blocking-timeout-milliseconds>5000</blocking-timeout-milliseconds> <idle-timeout-minutes>30</idle-timeout-minutes> <match-one/> </single-pool> </connectionmanager> </connectiondefinition-instance> </connection-definition> </outbound-resourceadapter> </resourceadapter> </connector>
デプロイメント・プランを作り、ドライバーをコピーしたら、次のステップは実際にデータ・ソースのコネクション・プールをデプロイすることです。もし Geronimo を始動していなければ、以下のコマンドで実行し、始動してください。
<geronimo_home>\bin\geronimo start
データ・ソースのコネクション・プールをデプロイするために、以下のコマンドを実行してください。
<geronimo_home>\bin\deploy --user system --password manager deploy <brokerage_home>\plan\mysql-geronimo-plan.xml ..\repository\org\tranql\tranql-connector-ra\1.3\tranql-connector-ra-1.3.rar
環境によりますが、以下のような確認メッセージが表示されるでしょう。
C:\geronimo-2.0\bin>deploy --user system --password manager deploy \brokerage\plan\mysql-geronimo-plan.xml
..\repository\org\tranql\tranql-connector-ra\1.3\tranql-connector-ra-1.3.rar
Deployed user/database-pool-HibernateDS/2.0/car
Apache Geronimo はHARアーカイブ形式をサポートしていないので、今回は全てのクラスをWARアーカイブの中に格納します。このアプリケーションをGeronimoで動かすためにクラスを2つ作成する必要があります。ひとつはGeronimo用のTransactionManagerLookupクラスで、もうひとつはセッション・ファクトリーを入手するためのユーティリティ・クラスHibernateUtilです。 それ以外にTradeDispatcherServlet とTradeDAOクラスに若干の変更を加える必要があります。
手始めに、アプリケーションに加えるべき変更点を下記のリストで眺めてみましょう。
TradeDAO
HibernateUtil
TradeDispatcherServlet
JBoss環境に於いては、HibernateMBeanがグローバルJNDIコンテキストへのセッション・ファクトリーを作成・バインドしてくれます。この機構により、単純なルックアップだけでセッション・ファクトリーを入手できるようになるわけです。セッションはセッション・ファクトリー経由で入手することができます。
}}{{{}TradeDAO.java は <brokerage_home>/src/com/dev/trade/dao ディレクトリーに存在します。
package com.dev.trade.dao; import java.sql.Connection; import java.sql.SQLException; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import java.util.Set; import javax.naming.InitialContext; import javax.naming.NamingException; import org.hibernate.Query; import org.hibernate.Session; import org.hibernate.SessionFactory; import com.dev.trade.bo.Stock; import com.dev.trade.bo.User; import com.dev.trade.bo.UserStock; import com.dev.trade.exception.DBException; import com.dev.trade.util.HibernateUtil; public class TradeDAO { SessionFactory factory = null; Session session = null; public TradeDAO() throws Exception { try { InitialContext ctx = new InitialContext(); factory = (SessionFactory)ctx.lookup("java:hibernate/BrokerageSessionFactory"); } catch (NamingException e1) { // TODO Auto-generated catch block e1.printStackTrace(); } } public User getUserByUserId(String userId) throws DBException { session = factory.getCurrentSession(); Query q = session.createQuery("from User u where u.userId=:userId"); q.setString("userId", userId); return (User) q.uniqueResult(); } ...
Geronimo環境ではセッション・ファクトリーを作成するための新しいユーティリティ・クラス、HibernateUtil classを作成することになります。
このクラスには、セッションを入手するための getCurrentSession()メソッドがあります。
TradeDAO.java の冒頭の箇所を以下の抜粋に従って修正します。
package com.dev.trade.dao; import java.sql.Connection; import java.sql.SQLException; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import java.util.Set; import org.hibernate.Query; import org.hibernate.Session; import com.dev.trade.bo.Stock; import com.dev.trade.bo.User; import com.dev.trade.bo.UserStock; import com.dev.trade.exception.DBException; import com.dev.trade.util.HibernateUtil; public class TradeDAO { Session session = null; public TradeDAO() throws Exception { } public User getUserByUserId(String userId) throws DBException { session = HibernateUtil.getCurrentSession(); Query q = session.createQuery("from User u where u.userId=:userId"); q.setString("userId", userId); return (User) q.uniqueResult(); } ...
以下の文字列を探索・置換します。
factory.getCurrentSession()
を
HibernateUtil.getCurrentSession()
で置換します。
9箇所が置換されるはずです。
セッションを入手する方法が、Apache Geronimo上でアプリケーションを動かすためのコード上の相違点の代表的なものです。
既に述べたとおり、このクラスはセッション・ファクトリーを作成し、アプリケーションにHibernateのセッションを提供するために使われます。このクラスのソース・コードは以下のようになります。
package com.dev.trade.util; import org.hibernate.HibernateException; import org.hibernate.Session; import org.hibernate.cfg.Configuration; /** * Configures and provides access to Hibernate sessions, tied to the * current thread of execution. Follows the Thread Local Session * pattern, see {@link http://hibernate.org/42.html}. */ public class HibernateUtil { /** location of the Hibernate Configuration File */ private static String CONFIG_FILE_LOCATION = "hibernate.cfg.xml"; /** Holds a single instance of Session */ private static final ThreadLocal threadLocal = new ThreadLocal(); /** The single instance of hibernate configuration */ private static final Configuration cfg = new Configuration(); /** The single instance of hibernate SessionFactory */ private static org.hibernate.SessionFactory sessionFactory; /** * Returns the ThreadLocal Session instance. Lazy initialize * the <code>SessionFactory</code> if needed. * * @return Session * @throws HibernateException */ public static Session getCurrentSession() throws HibernateException { Session session = (Session) threadLocal.get(); if (session == null || ! session.isConnected()) { if (sessionFactory == null) { try { cfg.configure(CONFIG_FILE_LOCATION); sessionFactory = cfg.buildSessionFactory(); } catch (Exception e) { System.err.println("%%%% Error Creating SessionFactory %%%%"); e.printStackTrace(); } } session = sessionFactory.openSession(); threadLocal.set(session); } return session; } /** * Close the single hibernate session instance. * * @throws HibernateException */ public static void closeSession() throws HibernateException { Session session = (Session) threadLocal.get(); if (session != null) { session.close(); } } }
HibernateUtil.java は <brokerage_home>/src/com/dev/trade/util ディレクトリーに配置します。ご参考までに、このファイルのコピーは既にサンプル・アプリケーションと一緒に提供されています。
このクラスにもセッション・ファクトリーを入手する際の相違点があります。JBossではセッション・ファクトリーの入手はJNDIコンテキスト経由で行いましたが、Geronimoではユーティリティ・クラス経由で行います。
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { Session hsession = null; try { InitialContext ctx = new InitialContext(); SessionFactory factory = (SessionFactory)ctx.lookup("java:hibernate/BrokerageSessionFactory"); hsession = factory.openSession(); } catch (NamingException e1) { e1.printStackTrace(); } Transaction tr = hsession.beginTransaction();
TradeDispatcherServlet.java は <brokerage_home>/src/com/dev/trade/servlet ディレクトリーに配置されています。doGetメソッドを以下の例に従って置換してください。
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { Transaction tr = HibernateUtil.getCurrentSession().getTransaction(); tr.begin();
Hibernateは色々なアプリケーション・サーバーようにトランザクション・マネージャーのルックアップ用のクラスを提供しています。残念ながら、Hibernate 3.2はApache Geronimo用のルックアップ用クラスを提供していませんので、自分たちで作らなくてはなりません。Geronimo用のトランザクション・マネージャーのルックアップ・クラスのコードは以下のようになります。
package org.hibernate.transaction; import java.util.Iterator; import java.util.Properties; import java.util.Set; import javax.transaction.TransactionManager; import org.hibernate.HibernateException; import org.hibernate.transaction.TransactionManagerLookup; import org.apache.geronimo.gbean.AbstractName; import org.apache.geronimo.gbean.AbstractNameQuery; import org.apache.geronimo.kernel.Kernel; import org.apache.geronimo.kernel.KernelRegistry; import org.apache.geronimo.kernel.proxy.ProxyManager; public class GeronimoTransactionManagerLookup implements TransactionManagerLookup { public static final String UserTransactionName = "java:comp/UserTransaction"; public TransactionManager getTransactionManager(Properties props) throws HibernateException { /* * try { Kernel kernel = KernelRegistry.getSingleKernel(); ProxyManager * proxyManager = kernel.getProxyManager(); AbstractNameQuery query = * new AbstractNameQuery(TransactionManager.class.getName()); Set names = * kernel.listGBeans(query); AbstractName name = null; for (Iterator it = * names.iterator(); it.hasNext();) name = (AbstractName) it.next(); * Object transMg = (Object) proxyManager.createProxy(name, * TransactionManager.class); return (TransactionManager)transMg; }catch * (Exception e) { e.printStackTrace(); System.out.println(); throw new * HibernateException("Geronimo Transaction Manager Lookup Failed", e); } */ try { Kernel kernel = KernelRegistry.getSingleKernel(); AbstractNameQuery query = new AbstractNameQuery(TransactionManager.class.getName ()); Set<AbstractName> names = kernel.listGBeans(query); if (names.size() != 1) { throw new IllegalStateException("Expected one transaction manager, not " + names.size()); } AbstractName name = names.iterator().next(); TransactionManager transMg = (TransactionManager) kernel.getGBean(name); return (TransactionManager)transMg; } catch (Exception e) { e.printStackTrace(); System.out.println(); throw new HibernateException("Geronimo Transaction Manager Lookup Failed", e); } } public String getUserTransactionName() { return UserTransactionName; } }
ご参考までに、このクラスは既に <brokerage_home>/TransactionManager ディレクトリーに配置されています。以下のようなディレクトリー構造を作り、そこに GeronimoTransactionManagerLookup.java をコピーしてください。
*brokerage_home>/src/org/hibernate/transaction
さて次にHibernateの構成ファイル hibernate-cfg.xml を作る必要があります。このファイルの中に必要なHibernateの構成上の属性を記述します。JBoss環境での hibernate-service.xml は hibernate-cfg.xml と同じ働きをしている点にご留意ください。ご参考までに、サンプルアプリケーションと共にこのファイルも既に <brokerage_home>/hibrenate ディレクトリーに提供されています。
<?xml version='1.0' encoding='utf-8'?> <!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd"> <hibernate-configuration> <session-factory> <!-- properties --> <property name="connection.datasource">java:comp/env/jdbc/HibernateDB</property> <property name="hibernate.transaction.manager_lookup_class"> org.hibernate.transaction.GeronimoTransactionManagerLookup </property> <property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property> <!-- Disable the second-level cache --> <property name="hibernate.cache.provider_class">org.hibernate.cache.NoCacheProvider</property> <property name="hibernate.current_session_context_class">org.hibernate.context.JTASessionContext</property> <!-- Echo all executed SQL to stdout --> <property name="hibernate.show_sql">true</property> <!-- Drop and re-create the database schema on startup --> <!--<property name="hibernate.hbm2ddl.auto">create</property> --> <!-- mapping files --> <mapping resource="Stock.hbm.xml"/> <mapping resource="UserStock.hbm.xml"/> <mapping resource="User.hbm.xml"/> </session-factory> </hibernate-configuration>
各々のプロパティ毎の詳細な機能説明についてはHibernareのマニュアルを参照してください。
ビルド前の最後のステップとして、Geronimo固有のデプロイメント記述子である geronimo-web.xml を作成します。以下の例を参照してください。またご参考までにこのファイルは <brokerage_home>/web/descriptors/geronimo ディレクトリーに既に提供されています。
<?xml version="1.0" encoding="ISO-8859-1"?> <web-app xmlns="http://geronimo.apache.org/xml/ns/j2ee/web-1.1" xmlns:naming="http://geronimo.apache.org/xml/ns/naming-1.1"> <dep:environment xmlns:dep="http://geronimo.apache.org/xml/ns/deployment-1.1"> <dep:moduleId> <dep:groupId>BrokerageApp</dep:groupId> <dep:artifactId>MySqlDS</dep:artifactId> <dep:version>2.0</dep:version> <dep:type>car</dep:type> </dep:moduleId> <dep:dependencies> <dep:dependency> <dep:groupId>user</dep:groupId> <dep:artifactId>database-pool-HibernateDB</dep:artifactId> <dep:version>2.0</dep:version> <dep:type>car</dep:type> </dep:dependency> </dep:dependencies> <dep:hidden-classes> <dep:filter>org.springframework</dep:filter> <dep:filter>META-INF/spring</dep:filter> <!--dep:filter>antlr</dep:filter--> </dep:hidden-classes> </dep:environment> <context-root>/brokerage</context-root> <resource-ref> <ref-name>jdbc/HibernateDB</ref-name> <resource-link>HibernateDS</resource-link> </resource-ref> </web-app>
<hidden-classes> エレメントは、warクラスローダーがクラス探索時にApache Geronimoの提供クラスを参照してしまうことで発生するかもしれないバーション不一致の問題を回避するための指定です。
サンプル・アプリケーションをビルドするには以下のコマンドを実行します。
set CLASSPATH=%CLASSPATH%;<hibernate_home>/lib/hibernate3.jar
<brokerage_home>/ant war
今回のオンライン仲介サンプル・アプリケーションは単なるWebアプリケーションなので war ターゲットを使っています。JBossのセクションではwarとharをパッケージするためにear形式を使いましたが、har形式はGeronimoではサポートされていません。
実行の結果、<brokerage_home>/geronimo-artefact ディレクトリーに brokerage.war ができます。
<brokerage_home>/solutions ディレクトリーにはコンパイルおよびGeronimo環境で稼動させるための移行済みのソースファイル類が含まれています。
移行したオンライン仲介サンプル・アプリケーションをデプロイするには、Geronimoサーバーが起動して正常稼動していることを確認してから以下のコマンドを実行します。
deploy --user system --password manager deploy <brokerage_home>/geronimo-artefact/brokerage.war
アプリケーションがデプロイされたら、Webブラウザーを開いて以下のURLにアクセスしてください。
http://localhost:8080/brokerage![]()
JBoss環境でアプリケーションをテストした時に使ったユーザー名、パスワードと同じものを指定してログインします。
この記事ではO/Rマッピング層にHibernateを使っているサンプル・アプリケーションをJBossからApache Geronimoへ移行する方法を紹介しました。JBossで提供されている機能・フィーチャーの全てが現時点のGeronimoでは実装されているわでけはないので、結果的に若干の追加のコーディングが必要でしたが、全体的な移行の難易度は低いものでした。