Jakarta EE / Java EE Advent Calendar 2025 の15日目の記事は、Jakarta EE 11 で新仕様として導入された Jakarata Data 1.0 についてイメージを掴むための内容となります。
1. はじめに
Jakarta EE(旧Java EE)を使用したエンタープライズJava開発において、データベースアクセスは常に重要な課題でした。これまで、データ永続化の標準は JPA (Jakarta Persistence API) が担ってきました。JPAは強力ですが、単純なCRUD操作であっても定型的なコード(ボイラープレート)が多くなりがちです。
クラウドネイティブ時代に向けた進化の中で、Spring Dataのような 「宣言的かつ規約ベース」 のアプローチを、標準仕様として求められJakarata Dataが登場しました。
2. Jakarta Data とは
Jakarta Dataは、Jakarta EE 11 標準仕様の一つです。データアクセス層の抽象化と生産性の向上を目的として策定されました。
簡単に言えば、ボイラープレートコードを大幅に削減し、宣言的な方法でリポジトリパターンを実装するための仕様です。
3. 動作環境
以降のサンプルコードを実行するための環境情報です。
検証済みの環境情報です。
- Java: JDK 21
- Build Tool: Maven 3.9+
(アプリケーションコードのビルド用) - コンテナエンジン: Docker Engine 29
(データベース用) - アプリケーションサーバ: GlassFish 8.0.0-M14
(Jakarta EE 11 互換のサーバで代替可能)
4. 実装:リポジトリインタフェース
今回は本の情報をデータベースで管理しており、操作するシーンを想定しています。
本情報となるBookエンティティは、以下の属性を持ちます。
このBookエンティティ情報を使ってデータベースを操作するクラスをJakarata Dataを使って実装していきます。
といっても、実際にはクラスではなくインタフェースの宣言しか実装しません。なぜなら、Jakarata Data側でインタフェースからクラスを自動で生成するためです。
Bookエンティティをベースにデータベースを操作する基本的なインタフェースの実装例がこちらです。
@Repository
public interface BookRepository extends CrudRepository<Book, Long> {
}
非常にシンプルですね。リポジトリパターンを使用して、インタフェースを実装していきます。以降、Bookリポジトリと呼びます。
Bookリポジトリは、Bookエンティティの情報に基づいて、データベースに取得・削除・挿入・更新処理ができます。これらの処理は継承しているCrudRepositoryで定義されているため、実装例が非常にシンプルとなっています。
Jakarata Dataで用意されているRepositoryは以下の3つです。
これらのリポジトリを継承するだけで、データベースのアクセス処理が自動で実装され、ビジネスロジック側の開発に集中することができます。
ビジネスロジックでアクセス処理を呼び出す場合は、以下のようになります。
@Inject
BookRepository repository;
...
Book book = repository.findById(id); // Book.idが指定した値と一致する情報をDBから取得
repository.delete(book); // 指定したBookエンティティ情報と一致する情報をDBから削除
repository.insertAll(books); // 指定した複数のBookエンティティ情報をDBに挿入
5. 実装:リポジトリメソッドの拡張
ここまでで、継承したリポジトリインタフェースに定義されたリポジトリメソッドの中身は自動で実装されるため、基本的な操作の実装はかなり楽にできることがイメージできたと思います。
Q: 定義されたリポジトリメソッドでは実現できないデータベースのアクセス処理はどうすれば良いでしょうか?
A: 自前で用意する必要があります。
主に使用するのが以下の2つのアノテーションです。
-
@Find: 引数名とエンティティのフィールド名が同じ場合、値が一致するデータを取得(検索) -
@Query: JDQL (Jakarta Data Query Language) または JPQL を用いたクエリ定義
@Findの使用例がこちらです。
@Repository
public interface BookRepository extends CrudRepository<Book, Long> {
@Find
Book searchBookByISBN(String isbn);
}
BookリポジトリにsearchBookByISBMリポジトリメソッドが定義されました。このリポジトリメソッドのisbn引数はBookエンティティのisbnフィールドと紐づいています。そのため、isbn引数に指定された値と一致する情報がDBから取得されBookエンティティとして返されます。
@Queryの使用例がこちらです。
@Repository
public interface BookRepository extends CrudRepository<Book, Long> {
@Find
Book searchBookByISBN(String isbn);
@Query("select Book from Book where title like ?1")
List<Book> searchBooksContainsTitle(String pattern);
@Query("where author like :pattern")
List<Book> searchBooksContainsAuthor(String pattern);
}
BookリポジトリにsearchBooksContainsTitle/searchBooksContainsAuthrorリポジトリメソッドが定義されました。このリポジトリメソッドは、@Queryに記載のクエリ文(JDQL)が実行されます。クエリ文の位置/名前付きパラメータは、リポジトリメソッドの引数に置換されます。そのため、pattern引数に指定された値(パターン)と一致する情報がDBから取得されBookエンティティとして変えられます。
ここでは紹介しきれない便利な機能がたくさんあります。
是非、関連ドキュメントを参照してください。
6. 動作:
本記事に記載の情報だけでは、アプリケーションが動作しません。
「参考」章に記載のサンプルコードを前提として説明します。
アプリケーションをビルドし、Jakarta EE 11互換のあるサーバにデプロイすることで、実際にアプリを動作させることができます。
データベースの起動
データベースをコンテナとして起動します。
docker-compose up -d
アプリケーションのビルド
Mavenコマンドを実行して、アプリケーションをビルドします。
mvn clean package
アプリケーションサーバ
GlassFishのコマンドでサーバを起動します。
asadmin start-domain
GlassFishのコマンドでアプリケーションをデプロイします。
asadmin deploy target/jakarta-data-sample.war
疎通確認
Webブラウザでhttp://localhost:8080/jakarta-data-sample/api/books にアクセスまたは、以下のコマンドを実行します。
curl -v http://localhost:8080/jakarta-data-sample/api/books
予めデータベースに保存していたデータが取得できることを確認できます。
[
{
"author": "Seiichiro Inoue, Noritaka Kagei",
"id": 1,
"isbn": "978-4-297-14680-1",
"price": 3740,
"publishedDate": "2025-02-27",
"title": "改訂3版 パーフェクトJava"
},
{
"author": "Seiichiro Inoue, Noritaka Kagei",
"id": 2,
"isbn": "978-4-297-14681-8",
"price": 3740,
"publishedDate": "2025-02-27",
"title": "改訂3版 パーフェクトJava(電子版)"
}
]
7. 参考
Jakarta Data の他機能を簡単に知りたい方向け
