JPAとは何ですか?Java PersistenceAPIの概要

仕様として、れるJava Persistence APIは、と懸念している永続緩くJavaオブジェクトは、それらを作成したアプリケーション・プロセスよりも長生きたことにより、任意のメカニズムを意味し、。すべてのJavaオブジェクトを永続化する必要はありませんが、ほとんどのアプリケーションは主要なビジネスオブジェクトを永続化します。JPA仕様では、ユーザーが定義することができますどのオブジェクトを永続化する必要がある、とどのようにそれらのオブジェクトは、Javaアプリケーションで永続化する必要があります。

JPA自体は、ツールやフレームワークではありません。むしろ、任意のツールまたはフレームワークで実装できる一連の概念を定義します。JPAのオブジェクトリレーショナルマッピング(ORM)モデルは、もともとHibernateに基づいていましたが、その後進化してきました。同様に、JPAはもともとリレーショナル/ SQLデータベースでの使用を目的としていましたが、一部のJPA実装はNoSQLデータストアで使用するために拡張されました。NoSQLでJPAをサポートする一般的なフレームワークは、JPA2.2のリファレンス実装であるEclipseLinkです。

JakartaEEのJPA2.2

Java Persistence APIは、Java EE5のEJB3.0仕様(JSR 220)のサブセットとして最初にリリースされました。その後、Java EE 6(JSR 317)のJPA 2.0のリリース以降、独自の仕様として進化しました。これを書いている時点で、JPA2.2はJakartaEEの一部として継続のために採用されています。

JPAとHibernate

それらの絡み合った歴史のために、HibernateとJPAは頻繁に混同されます。ただし、Javaサーブレット仕様と同様に、JPAは多くの互換性のあるツールとフレームワークを生み出しました。Hibernateはそのうちの1つにすぎません。

Gavin Kingによって開発され、2002年の初めにリリースされた、HibernateはJava用のORMライブラリです。Kingは、永続性のためにエンティティBeanの代替としてHibernateを開発しました。このフレームワークは非常に人気があり、当時必要だったため、そのアイデアの多くが最初のJPA仕様で採用および体系化されました。

今日、Hibernate ORMは最も成熟したJPA実装の1つであり、JavaでのORMの人気のあるオプションです。Hibernate ORM 5.3.8(この記事の執筆時点での現在のバージョン)はJPA2.2を実装しています。さらに、Hibernateのツールファミリーは、Hibernate Search、Hibernate Validator、NoSQLのドメインモデル永続性をサポートするHibernateOGMなどの一般的なツールを含むように拡張されました。

JPAとEJB

前述のように、JPAはEJB 3.0のサブセットとして導入されましたが、その後、独自の仕様として進化してきました。EJBは、JPAとは焦点が異なる仕様であり、EJBコンテナに実装されています。各EJBコンテナには、JPA仕様で定義されている永続層が含まれています。

Java ORMとは何ですか?

それらは実行が異なりますが、すべてのJPA実装はある種のORMレイヤーを提供します。JPAおよびJPA互換ツールを理解するには、ORMを十分に理解する必要があります。

オブジェクトリレーショナルマッピングはタスクです。開発者が手動で行うことを避ける十分な理由があるタスクです。Hibernate ORMやEclipseLinkのようなフレームワークは、そのタスクをライブラリまたはフレームワーク、ORMレイヤーに体系化します。アプリケーションアーキテクチャの一部として、ORMレイヤーは、リレーショナルデータベースのテーブルと列と対話するためのソフトウェアオブジェクトの変換を管理する役割を果たします。Javaでは、ORMレイヤーはJavaクラスとオブジェクトを変換して、リレーショナルデータベースに格納および管理できるようにします。

デフォルトでは、永続化されるオブジェクトの名前がテーブルの名前になり、フィールドが列になります。テーブルが設定されると、各テーブル行はアプリケーション内のオブジェクトに対応します。オブジェクトマッピングは構成可能ですが、デフォルトでうまく機能する傾向があります。

NoSQLを使用したJPA

ごく最近まで、非リレーショナルデータベースは珍しい好奇心でした。NoSQLの動きはそれをすべて変え、Java開発者はさまざまなNoSQLデータベースを利用できるようになりました。Hibernate OGMやEclipseLinkなど、一部のJPA実装はNoSQLを採用するように進化しています。

図1は、アプリケーション開発におけるJPAとORMレイヤーの役割を示しています。

JavaWorld /

JavaORMレイヤーの構成

JPAを使用するように新しいプロジェクトをセットアップするときは、データストアとJPAプロバイダーを構成する必要があります。選択したデータベース(SQLまたはNoSQL)に接続するようにデータストアコネクタを構成します。また、HibernateやEclipseLinkなどのフレームワークであるJPAプロバイダーを含めて構成します。JPAは手動で構成できますが、多くの開発者はSpringのすぐに使用可能なサポートを使用することを選択します。手動およびSpringベースのJPAのインストールとセットアップの両方のデモンストレーションについては、以下の「JPAのインストールとセットアップ」を参照してください。

Javaデータオブジェクト

Java Data Objectsは、主にオブジェクトの永続性ロジックをサポートし、非リレーショナルデータストアを操作するための長年のサポートによって、JPAとは異なる標準化された永続性フレームワークです。JPAとJDOは十分に類似しているため、JDOプロバイダーもJPAを頻繁にサポートします。JPAやJDBCなどの他の永続性標準に関連するJDOの詳細については、ApacheJDOプロジェクトを参照してください。

Javaでのデータの永続性

プログラミングの観点からは、ORMレイヤーはアダプターレイヤーです。オブジェクトグラフの言語をSQLおよびリレーショナルテーブルの言語に適合させます。ORMレイヤーを使用すると、オブジェクト指向の開発者は、オブジェクト指向のパラダイムを離れることなく、データを永続化するソフトウェアを構築できます。

JPAを使用する場合は、データストアからアプリケーションのデータモデルオブジェクトへのマップを作成します。オブジェクトの保存方法と取得方法を定義する代わりに、オブジェクトとデータベース間のマッピングを定義してから、JPAを呼び出してオブジェクトを永続化します。リレーショナルデータベースを使用している場合、アプリケーションコードとデータベース間の実際の接続の多くは、Java Database ConnectivityAPIであるJDBCによって処理されます。

仕様として、JPAはメタデータアノテーションを提供します。これを使用して、オブジェクトとデータベース間のマッピングを定義します。各JPA実装は、JPAアノテーション用の独自のエンジンを提供します。JPA仕様には、JPAシステムとの主要な接点であるPersistanceManagerorも含まれていますEntityManager(ビジネスロジックコードは、マップされたオブジェクトをどう処理するかをシステムに指示します)。

これらすべてをより具体的にするために、ミュージシャンをモデル化するための単純なデータクラスであるリスト1を検討してください。

リスト1.Javaの単純なデータクラス

 public class Musician { private Long id; private String name; private Instrument mainInstrument; private ArrayList performances = new ArrayList(); public Musician( Long id, String name){ /* constructor setters... */ } public void setName(String name){ this.name = name; } public String getName(){ return this.name; } public void setMainInstrument(Instrument instr){ this.instrument = instr; } public Instrument getMainInstrument(){ return this.instrument; } // ...Other getters and setters... } 

Musicianリスト1のクラスは、データを保持するために使用されます。名前フィールドなどのプリミティブデータを含めることができます。また、mainInstrumentやなどの他のクラスとの関係を保持することもできperformancesます。

Musician理由は、データを含めることです。このタイプのクラスは、DTOまたはデータ転送オブジェクトと呼ばれることもあります。DTOは、ソフトウェア開発の一般的な機能です。それらは多くの種類のデータを保持しますが、ビジネスロジックは含まれていません。データオブジェクトの永続化は、ソフトウェア開発における遍在する課題です。

JDBCによるデータの永続性

Musicianクラスのインスタンスをリレーショナルデータベースに保存する1つの方法は、JDBCライブラリを使用することです。JDBCは、基盤となるデータベースの実装について考えることなく、アプリケーションがSQLコマンドを発行できるようにする抽象化レイヤーです。

リスト2は、MusicianJDBCを使用してクラスを永続化する方法を示しています。

リスト2.レコードを挿入するJDBC

 Musician georgeHarrison = new Musician(0, "George Harrison"); String myDriver = "org.gjt.mm.mysql.Driver"; String myUrl = "jdbc:mysql://localhost/test"; Class.forName(myDriver); Connection conn = DriverManager.getConnection(myUrl, "root", ""); String query = " insert into users (id, name) values (?, ?)"; PreparedStatement preparedStmt = conn.prepareStatement(query); preparedStmt.setInt (1, 0); preparedStmt.setString (2, "George Harrison"); preparedStmt.setString (2, "Rubble"); preparedStmt.execute(); conn.close(); // Error handling removed for brevity 

リスト2のコードは、かなり自己文書化されています。georgeHarrisonオブジェクトは、どこにでも(提出フロントエンド、外部サービスなど)から来ることができ、そのIDと名前のフィールドが設定されています。次に、オブジェクトのフィールドを使用して、SQLinsertステートメントの値を指定します。(このPreparedStatementクラスはJDBCの一部であり、SQLクエリに値を安全に適用する方法を提供します。)

JDBCでは手動構成に伴う制御が可能ですが、JPAと比較すると面倒です。データベースを変更するには、最初に、JavaオブジェクトからリレーショナルデータベースのテーブルにマップするSQLクエリを作成する必要があります。その後、オブジェクトの署名が変更されるたびにSQLを変更する必要があります。JDBCを使用すると、SQLの保守自体がタスクになります。

JPAによるデータの永続性

次に、MusicianJPAを使用してクラスを永続化するリスト3について考えてみます。

リスト3.JPAを使用したGeorgeHarrisonの永続化

 Musician georgeHarrison = new Musician(0, "George Harrison"); musicianManager.save(georgeHarrison); 

リスト3は、リスト2の手動SQLを、session.save()JPAにオブジェクトを永続化するように指示する1行に置き換えます。それ以降、SQL変換はフレームワークによって処理されるため、オブジェクト指向のパラダイムを離れる必要はありません。

JPAのメタデータアノテーション

リスト3の魔法は、JPAのアノテーションを使用して作成された構成の結果です。開発者はアノテーションを使用して、どのオブジェクトを永続化する必要があるか、およびどのように永続化する必要があるかをJPAに通知します。

リスト4は、Musician単一のJPAアノテーションを持つクラスを示しています。

リスト4.JPAの@Entityアノテーション

 @Entity public class Musician { // ..class body } 

Persistent objects are sometimes called entities. Attaching @Entity to a class like Musician informs JPA that this class and its objects should be persisted.

XML vs. annotation-based configuration

JPA also supports using external XML files, instead of annotations, to define class metadata. But why would you do that to yourself?

Configuring JPA

Like most modern frameworks, JPA embraces coding by convention (also known as convention over configuration), in which the framework provides a default configuration based on industry best practices. As one example, a class named Musician would be mapped by default to a database table called Musician.

The conventional configuration is a timesaver, and in many cases it works well enough. It is also possible to customize your JPA configuration. As an example, you could use JPA's @Table annotation to specify the table where the Musician class should be stored.

Listing 5. JPA's @Table annotation

 @Entity @Table(name="musician") public class Musician { // ..class body } 

Listing 5 tells JPA to persist the entity (Musician class) to the musician table.

Primary key

In JPA, the primary key is the field used to uniquely identify each object in the database. The primary key is useful for referencing and relating objects to other entities. Whenever you store an object in a table, you will also specify the field to use as its primary key.

In Listing 6, we tell JPA what field to use as Musician's primary key.

Listing 6. Specifying the primary key

 @Entity public class Musician { @Id private Long id; 

In this case, we've used JPA's @Id annotation to specify the id field as Musician's primary key. By default, this configuration assumes the primary key will be set by the database--for instance, when the field is set to auto-increment on the table.

JPA supports other strategies for generating an object's primary key. It also has annotations for changing individual field names. In general, JPA is flexible enough to adapt to any persistence mapping you might need.

CRUD operations

Once you've mapped a class to a database table and established its primary key, you have everything you need to create, retrieve, delete, and update that class in the database. Calling session.save() will create or update the specified class, depending on whether the primary-key field is null or applies to en existing entity. Calling entityManager.remove() will delete the specified class.

Entity relationships in JPA

Simply persisting an object with a primitive field is only half the equation. JPA also has the capability to manage entities in relation to one another. Four kinds of entity relationships are possible in both tables and objects:

    1. One-to-many
    2. Many-to-one
    3. Many-to-many
    4. One-to-one

Each type of relationship describes how an entity relates to other entities. For example, the Musician entity could have a one-to-many relationship with Performance, an entity represented by a collection such as List or Set.

If the Musician included a Band field, the relationship between these entities could be many-to-one, implying collection of Musicians on the single Band class. (Assuming each musician only performs in a single band.)

If Musician included a BandMates field, that could represent a many-to-many relationship with other Musician entities.

最後に、Musician持っているかもしれない1対1の関係Quote有名な引用を表すために使用されるエンティティを、: Quote famousQuote = new Quote()

関係タイプの定義

JPAには、関係マッピングタイプごとに注釈があります。リスト7は、MusicianPerformancesの間の1対多の関係に注釈を付ける方法を示しています。

リスト7.1対多の関係に注釈を付ける