Jakarta Persistence、Hibernate、および Spring Data JPA

最終更新: 2026-03-29 19:32:52 +0800 +0800
原文は英語で書かれています。あなたはAI翻訳版を読んでいます。

Jakarta Persistence は、オブジェクト関係マッピングのための標準 Java API を定義します。Hibernate は広く利用されている実装です。Spring Data JPA は、Jakarta Persistence プロバイダーの上にリポジトリー抽象化を構築します。

Jakarta Persistence モデル #

アプリケーションでは、@Entity、@Table、@Id、@Column などのアノテーションを使用して、通常のクラスをデータベーステーブルにマッピングします。

java
@Entity
@Table(name = "orders")
public class PurchaseOrder {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Column(nullable = false)
    private String status;
}

標準 API は jakarta.persistence にあります。実装は、Java のサービスプロバイダー機構を通じて jakarta.persistence.spi.PersistenceProvider を検出します。プロバイダーは、永続化操作および JPQL や Criteria クエリーをデータベース固有の SQL に変換します。

スタンドアロンアプリケーションでは、META-INF/persistence.xml に永続化ユニットを定義し、EntityManagerFactory を作成して、アプリケーションの停止時にクローズします。

java
EntityManagerFactory emf =
        Persistence.createEntityManagerFactory("application");
try {
    EntityManager em = emf.createEntityManager();
    // 変更処理の前後でトランザクションを開始およびコミットする
    em.close();
} finally {
    emf.close();
}

永続化ユニットは、プロバイダー、管理対象エンティティクラス、データソースまたは JDBC 設定、およびプロバイダーのプロパティを提供します。persistence.xml にデータベースパスワードを埋め込むのではなく、コンテナー管理のデータソースと外部化した認証情報を優先してください。

エンティティーマネージャー、トランザクション、およびクエリー #

EntityManager は永続化コンテキストを表します。そのコンテキスト内では、1 つの管理対象 Java オブジェクトのアイデンティティが、1 つのデータベースアイデンティティに対応します。エンティティーの永続化、マージ、削除、およびクエリーは、適切なトランザクション内で実行してください。EntityManagerFactory は高コストでアプリケーションスコープです。一方、EntityManager は通常、リクエストスコープまたはトランザクションスコープであり、スレッドセーフではありません。

JPQL では、テーブルやカラムではなく、エンティティー名とプロパティーをクエリーします。

java
List<PurchaseOrder> orders = em.createQuery(
        "select o from PurchaseOrder o where o.status = :status",
        PurchaseOrder.class)
    .setParameter("status", "PAID")
    .getResultList();

入力を JPQL に連結するのではなく、名前付きパラメーターを使用してください。動的クエリーには、Criteria API がプログラムによる代替手段を提供します。

Hibernate #

Hibernate は Jakarta Persistence を実装し、オプションのネイティブ機能も提供します。移植性を維持するため、まず標準 API を使用してください。Hibernate の拡張機能は、その価値が明確な場合にのみ使用し、それによって生じるベンダー依存性を文書化してください。

遅延関連は、アクセスされるまでフェッチを遅延させます。これにより不要な処理を避けられますが、永続化コンテキストの外部では LazyInitializationException が発生し、永続化コンテキスト内では N+1 クエリー問題を引き起こす可能性があります。フェッチ結合、エンティティーグラフ、バッチ処理、またはプロジェクションを使用してフェッチ計画を明示的に設計してください。すべての関連を EAGER にすることで、あらゆる問題を解決しようとはしないでください。

スキーマ生成はローカル開発には便利ですが、本番環境のスキーマ変更はレビューしたうえで、マイグレーションツールを通じて適用してください。

Spring Data JPA リポジトリー #

Spring Data は、Repository、一般的には JpaRepository を拡張するインターフェイスのリポジトリー実装を生成できます。

java
public interface PurchaseOrderRepository
        extends JpaRepository<PurchaseOrder, Long> {
    List<PurchaseOrder> findByStatus(String status);
}

Spring は設定または Boot の自動設定を通じてリポジトリーを検出し、Bean としてのライフサイクルを管理します。JpaRepository は CRUD、ページング、およびソートのメソッドを提供します。派生クエリー名は単純な述語に有用です。メソッド名が不明確になる場合は、@Query、Specification、またはカスタムリポジトリーを使用してください。

複数のリポジトリーまたは外部作用を伴うビジネス処理では、トランザクション境界をサービス層に配置します。読み取り専用トランザクションは意図を伝え、プロバイダーの最適化を可能にしますが、セキュリティー機構ではありません。

コメント

GitHub で閲覧・コメントする(投稿にはログインが必要です)