8 HibernateからTopLinkへの移行
この章では、HibernateのJPA注釈およびネイティブな独自のAPIを使用するアプリケーションをEclipseLinkのJPAを使用するように移行する方法を説明します。この移行では、Hibernateの注釈をEclipseLinkの注釈に移行すること、およびHibernateのネイティブAPIをEclipseLinkのJPAにアプリケーションのコードで変換することを行います。標準のJPA注釈およびAPIは変更されません。
この章の内容は次のとおりです。
ユース・ケース
開発者は、Hibernateではなく、TopLinkを永続性プロバイダとして使用するようアプリケーションを移行したいと考えています。
解決方法
この章の手順に従って、アプリケーションをアップグレードします。
コンポーネント
-
TopLink 12c (12.1.2.0.0)以上。
注意:
TopLinkのコア機能は、オープン・ソースのEclipse Foundationの永続性フレームワークであるEclipseLinkによって提供されています。EclipseLinkでは、Java Persistence API (JPA)、Java Architecture for XML Binding (JAXB)、および標準に基づいたその他の永続性テクノロジと、それらの標準の拡張が実装されます。TopLinkには、EclipseLinkのすべてに加え、Oracleの追加機能が含まれています。
-
EclipseLink 2.4以降。
ソリューションの概要
Hibernateは、Java環境のためのオブジェクト・リレーショナル・マッピング(ORM)ツールです。これは、Javaオブジェクトをリレーショナル・データベース・アーティファクトにマッピングしたり、Javaのデータ型をSQLのデータ型にマッピングしたりするためのフレームワークを提供します。また、データベースに問い合せて、データを取得することもできます。
Hibernateの詳細は、http://www.hibernate.org
を参照してください。
移行の理由
HibernateからTopLinkに移行する理由には、次のようなものがあります。
-
パフォーマンスとスケーラビリティ: EclipseLinkのキャッシング・アーキテクチャでは、オブジェクトの作成を最小限に抑えて、インスタンスを共有できます。EclipseLinkのキャッシングでは、シングルノードおよびクラスタ化されたデプロイメントがサポートされています。
-
主要なリレーショナル・データベースのサポート: EclipseLinkでは、すべての主要なリレーショナル・データベースとそれに固有な拡張を継続的にサポートします。EclipseLinkはOracle Databaseに対する最高のORMソリューションでもあります。
-
包括的な永続性ソリューション: EclipseLinkには、業界をリードするオブジェクトリレーショナル・サポートが用意されていますが、さらにコア・マッピング機能も使用して、Object-XML (JAXB)、サービス・データ・オブジェクト(SDO)およびデータベースWebサービス(DBWS)が提供されています。要件に応じて、同じコア永続性エンジンに基づく永続性サービスを複数使用することもできます。
-
JPAのサポート: EclipseLinkは、JPAの参照実装で、JPAの今後のバージョンをサポートします。
メイン・タスク
Hibernateを永続性プロバイダとして使用するアプリケーションでTopLinkに移行するには、次のタスクを実行します。
タスク1: 前提条件
TopLink 12c (12.1.2.0.0)以上。
http://www.oracle.com/technetwork/middleware/toplink/downloads/index.html
からTopLinkをダウンロードします。
EclipseLink 2.4以降。
http://www.eclipse.org/eclipselink/downloads/
からEclipseLinkをダウンロードします。
タスク1: Hibernateのエンティティ注釈の変換
org.hibernate.annotations.Entity
クラスで定義されているHibernateのエンティティ注釈には、JPAの標準@Entity
注釈で定義されている内容を超えるメタデータが追加されています。
例8-1に、Hibernateのエンティティ注釈のサンプルを示します。この例では、selectBeforeUpdate
、dynamicInsert
、dynamicUpdate
、optimisticLock
およびpolymophism
属性が使用されています。Hibernateのエンティティ注釈には、この例には示されていないmutable
およびpersister
属性も定義されています。
例8-1 Hibernateのエンティティ注釈のサンプル
@org.hibernate.annotations.Entity( selectBeforeUpdate = true, dynamicInsert = true, dynamicUpdate = true, optimisticLock = OptimisticLockType.ALL, polymorphism = PolymorphismType.EXPLICIT)
次の項では、選択、ロック、多相性、動的更新および挿入をEclipseLinkが処理する方法を説明します。詳細は、Eclipselinkのドキュメントの「EclipseLink/Examples/JPA/Migration/Hibernate/V3Annotations」を参照してください。
http://wiki.eclipse.org/EclipseLink/Examples/JPA/Migration/Hibernate/V3Annotations
SelectBeforeUpdate、dynamicInsertおよびdynamicUpdate属性の変換
HibernateでselectBeforeUpdate
属性を指定すると、オブジェクトが実際に変更されたことが確実な場合以外、HibernateはSQL UPDATEを実行しません。dynamicInsert
属性を指定すると、INSERT
SQL
文が実行時に生成されて、null以外の値の列のみがストアされます。dynamicUpdate
属性を指定すると、UPDATE
SQL
文が実行時に生成されて、値が変更された列のみをストアできます。
EclipseLinkのデフォルトでは、マップされたすべての列が常に挿入され、変更された列のみが更新されます。代替操作が必要な場合は、Javaコード、SQLまたはストアド・プロシージャを使用して、これらの操作に使用される問合せをカスタマイズできます。
OptimisticLock属性の変換
Hibernateでは、optimisticLock
属性によって、オプティミスティック・ロックの戦略が決まります。
EclipseLinkのオプティミスティック・ロック機能では、Hibernateのすべてのロック・タイプに加えて他のタイプもサポートされています。表8-1に、Hibernateの@Entity(optimisticLock)
属性に対応するEclipseLinkのロッキング・ポリシーを示します。これらのポリシーは、EclipseLinkの@OptimisticLocking
注釈またはEclipseLinkのorm.xml
ファイルのどちらかで構成できます。詳細は、@OptimisticLockingを参照してください。
表8-1 Hibernateのオプティミスティック・ロックからEclipseLinkのオプティミスティック・ロックへの変換
HibernateのOptimisticLockタイプ | 説明 | EclipseLinkのOptimisticLocking |
---|---|---|
|
オプティミスティック・ロックなし |
EclipseLinkはデフォルトでオプティミスティック・ロックなしになります。 |
|
列バージョンを使用 |
JPA
|
|
変更された列を比較 |
JPA
|
|
すべての列を比較 |
EclipseLinkの次の注釈が使用されます。
|
さらに、EclipseLinkでは、OptimisticLockingType.SELECTED_COLUMNS
注釈を使用して、選択した列の特定のセットも比較できます。これにより、CHANGED
またはALL
の戦略がニーズに合わない場合に、比較する必要がある重要な列を選択できます。
タスク2: Hibernateのカスタム・シーケンス・ジェネレータ注釈の変換
Hibernateでは、@GeneratedValue
注釈によって、ID生成戦略を定義します。@GenericGenerator
では、Hibernate固有のIDジェネレータを定義できます。例8-2は、シーケンス値のカスタム・ジェネレータを示しています。
例8-2 シーケンス値のカスタム・ジェネレータ
. . . @Id @GeneratedValue(generator = "system-uuid") @GenericGenerator(name = "system-uuid", strategy = "mypackage.UUIDGenerator") public String getTransactionGuid() . . .
EclipseLinkでは、@GeneratedValue
注釈を使用して、カスタム・シーケンス・ジェネレータを実装および登録できます。詳細は、次のEclipseLinkのドキュメントのカスタム・シーケンスの使用方法に関する項を参照してください。
http://wiki.eclipse.org/EclipseLink/Examples/JPA/CustomSequencing
タスク3: Hibernateのマッピング注釈の変換
次の項では、Hibernateの様々な注釈をEclipseLinkの注釈に変換する方法を説明します。
@ForeignKey注釈の変換
Hibernateの@ForeignKey
注釈では、スキーマ生成時に使用する外部キーの名前を定義できます。
EclipseLinkでは、外部キーに妥当な名前を生成し、使用する名前を指定するための注釈やeclipselink-orm.xml
はサポートしていません。移行時には、EclipseLinkでスキーマ(DDL)コマンドをデータベースに直接生成するのではなく、スクリプト・ファイルに生成することをお薦めします。そうすれば、実行する前に、別の名前を使用するようにスクリプトをカスタマイズできます。
注意:
外部キー名はEclipseLinkでは実行時に使用されませんが、EclipseLinkがスキーマを削除しようとする場合には必要です。この場合、削除スクリプトをファイルに生成して、作成時に使用された外部キー名と一致するようにカスタマイズする必要があります。
@Cache注釈の変換
Hibernateでは、@Cache
注釈によって、エンティティおよびリレーションシップのキャッシングを構成します。EclipseLinkでは、データ・キャッシュではなくエンティティ・キャッシュが使用されるので、リレーションシップは自動的にキャッシュされます。これらの場合、@Cache
注釈を移行時に削除する必要があります。@Cache
注釈がエンティティに使用されている場合は、EclipseLinkの@Cache
注釈と同様の動作になります。@Cache
注釈および同等のeclipselink-orm.xml
構成値の詳細は、『Oracle TopLink Java Persistence API (JPA)拡張機能リファレンス』を参照してください。
タスク4: persistence.xmlファイルの変更
persistence.xml
ファイルは、JPA永続性のデプロイメント・ディスクリプタ・ファイルです。ここには、永続性ユニットを指定し、管理対象永続性クラス、オブジェクト・リレーショナル・マッピング、およびデータベース接続の詳細を宣言します。例8-3に、Hibernateを使用するアプリケーションのpersistence.xml
ファイルを示します。Hibernateに固有の値は、太字のフォントで示します。
例8-3 Hibernateを使用するアプリケーションの永続性ファイル
<persistence> <persistence-unit name="helloworld"><provider>org.hibernate.ejb.HibernatePersistence</provider>
<jta-data-source>java:/DefaultDS</jta-data-source> <properties><property name="hibernate.dialect" value="org.hibernate.dialect.HSQLDialect"/>
<property name="hibernate.hbm2ddl.auto" value="create-drop"/>
</properties> </persistence-unit> </persistence>
変更されたpersistence.xmlファイル
例8-4に、EclipseLinkを使用するアプリケーション用に変更されたpersistence.xml
ファイルを示します。主な相違は、永続性プロバイダの値などです。EclipseLinkの場合は、この値は、org.eclipse.persistence.jpa.PersistenceProvider
です。EclipseLink固有のプロパティ名には、通常、eclipselink.target-database
のようにeclipselink
という接頭辞が付きます。EclipseLinkに固有の値は、太字のフォントで示します。
例8-4 EclipseLink用に変更された永続性ファイル
<xml version="1.0" encoding="UTF-8"?> <persistence version="1.0" xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd"> <persistence-unit name="helloworld"><provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
<jta-data-source>java:/DefaultDS</jta-data-source> <!-- For Java SE applications, entity classes must be specified for EclipseLink weaving. For Java EE applications, the classes are found automatically. --> <class>Todo</class> <properties><property name="eclipselink.ddl-generation" value="drop-and-create-tables"/>
<property name="eclipselink.ddl-generation.output-mode" value="database"/>
<property name="eclipselink.logging.level" value="FINE"/>
</properties> </persistence-unit> </persistence>
データベース表の削除および作成
本番環境では、通常はデータベースにスキーマが設定されています。永続性ユニットに定義されている次のプロパティは、例およびデモ用に適しています。これらのプロパティを指定すると、EclipseLinkでデータベース表が自動的に削除および作成されます。以前に存在した表は削除されます。
データベース表の削除および作成機能を使用するには、次のプロパティをpersistence.xml
ファイルに追加します。
<property name="eclipselink.ddl-generation" value="drop-and-create-tables"/> <property name="eclipselink.ddl-generation.output-mode" value="database"/>
この機能の詳細は、『Oracle TopLink Java Persistence API (JPA)拡張機能リファレンス』のddl-generationに関する項のdrop-and-create-tables
のエントリを参照してください。
データベース表の作成または拡張
データベース表の作成または拡張機能では、新しいデータベース表を作成したり、既存の表を変更することによって、データベース・スキーマとオブジェクト・モデルを一致させることができます。フィールド名の変更を指定したり、フィールドを追加および削除することによって、既存の表を変更できます。
注意:
現在のリリースでは、データベース表の作成または拡張機能では、既存の列を名前変更したり削除できません。欠落している表の列のみを追加できます。
データベース表の作成または拡張機能では、テスト・データを再移入する必要を減らせます。オブジェクト・モデルの変更により、スキーマの変更時に、データベース表の削除および作成機能の使用を回避できます。また、データベース表の作成または拡張機能では、表の列を追加する拡張も使用できます。
データベース表の作成または拡張機能を使用するには、次のプロパティをpersistence.xml
ファイルに追加します。コンテキストがロードされたら、永続性ユニットで必要とされる各表のデータベースに対し、EclipseLinkが問合せを行い、その結果を使用して表を作成または拡張する必要があるか判断されます。
<property name="eclipselink.ddl-generation" value="create-or-extend-tables" /> <property name="eclipselink.ddl-generation.output-mode" value="database" />
この機能の詳細は、『Oracle TopLink Java Persistence API (JPA)拡張機能リファレンス』のddl-generationに関する項のcreate-or-extend-tables
のエントリを参照してください。
タスク5: Hibernate APIからEclipseLink APIへの変換
表8-2で、JPAプロジェクトでよく使用されるHibernateクラスおよび同等のEclipseLink (JPA)インタフェースを説明します。Hibernateのすべてのクラスはorg.hibernate
パッケージにあります。すべてのJPAインタフェース(およびPersistence
クラス)はjavax.persistence
パッケージにあります。
EclipseLinkのAPIの詳細は、Oracle TopLink Java APIリファレンスを参照してください。
表8-2 Hibernateのクラスおよび同等のJPAインタフェース
org.hibernate | javax.persistence | 説明 |
---|---|---|
|
|
セッション・ファクトリ(Hibernate内)またはエンティティ・マネージャ・ファクトリ(JPA内)を構成するブートストラップ・クラスを提供します。通常、これはJVM用の単一のセッション(またはエンティティ・マネージャ)ファクトリを作成するために使用します。 |
|
|
Hibernateセッション(またはJPAエンティティ・マネージャ)をオープンして、ユーザー・リクエストを処理するためのAPIを提供します。一般に、セッション(またはエンティティ・マネージャ)は、クライアント・リクエストを処理するスレッドごとにオープンされます。 |
|
|
エンティティをデータベースにストアまたはデータベースからロードするためのAPIを提供します。トランザクションを取得して問合せを作成するためのAPIも提供します。 |
|
|
トランザクションを管理するためのAPIを提供します。 |
|
|
問合せを実行するためのAPIを提供します。 |
その他の参考資料
この章のソリューションが実装されているその他のテクノロジおよびツールの詳細は、次の参考資料を参照してください。
-
http://www.hibernate.org
のHibernate。 -
EclipseLinkのドキュメント(
http://wiki.eclipse.org/EclipseLink/Examples/JPA/Migration/Hibernate
)の「EclipseLink/Examples/JPA/Migration/Hibernate」。