Spring Data JPAを使っていると、EntityやRepositoryは書けるものの、「どこまでがJPAで、Spring Data JPAが何を追加しているのか」が曖昧になりがちです。役割を分けて理解すると、saveやQueryで迷ったときの切り分けが速くなります。
まず結論:Spring Data JPAはJPAの上でRepository実装を省力化する
JPAはJavaで永続化を扱うための仕様です。Spring Data JPAは、そのJPAを利用しながらRepository抽象化やクエリ生成などを提供し、典型的なデータアクセスコードを減らします。
用語解説:Repository
ドメインオブジェクトの保存・取得など、永続化アクセスをまとめる境界です。Spring Dataではインターフェースを定義し、基本CRUDの実装をフレームワークへ委ねられます。
(JPA自体とJDBCの違いから整理したい場合については『【保存版】JPA vs JDBCを徹底比較!メリット・デメリットと使い分け』をご参照ください)
1. Entityは永続化するクラスを表す
Jakarta Persistenceでは、Entityクラスは@Entityで示し、主キーを持つ必要があります。Spring Boot 3系以降のコード例ではjakarta.persistenceパッケージを使う構成が一般的です。
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.Id;
@Entity
public class User {
@Id
@GeneratedValue
private Long id;
private String name;
protected User() {}
public void setName(String name) {
this.name = name;
}
}
2. Repositoryインターフェースで基本CRUDを受け取る
Spring DataのRepository抽象化では、CrudRepositoryやJpaRepositoryなどを継承して、保存・検索・削除の基本操作を利用できます。実装クラスを毎回手書きしないことが大きな利点です。
import org.springframework.data.jpa.repository.JpaRepository;
public interface UserRepository
extends JpaRepository<User, Long> {
}
3. saveは新規Entityと既存Entityで内部処理が分かれる
Spring Data JPAの公式リファレンスでは、saveはEntityが新規ならEntityManager.persist、既存と判定されればEntityManager.mergeを使うと説明されています。単に「必ずINSERTするメソッド」と覚えない方が安全です。
User user = new User();
user.setName("Sato");
User saved = userRepository.save(user);
実際のSQL発行タイミングはflushやトランザクション境界にも関係します。saveの呼び出し位置だけでSQLの発行時点を断定しないようにします。
4. 単純な検索はメソッド名からQueryを組み立てられる
Spring Data JPAでは、一定の命名規則に沿ったRepositoryメソッドから検索条件を組み立てられます。単純な条件ならSQLやJPQLを直接書かずに意図を表現できます。
import java.util.List;
List<User> findByName(String name);
List<User> findByNameContaining(String keyword);
5. 複雑な検索では@Queryを使う
メソッド名が長くなりすぎる、JOINや集計などクエリを明示したい場合は@Queryを検討します。JPQLとnativeQueryを混同せず、必要性に応じて選びます。
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
@Query("select u from User u where u.name = :name")
List<User> searchByName(@Param("name") String name);
(Repositoryの@QueryやnativeQueryを詳しく確認したい場合については『Spring Boot Repository徹底解説|@Query・nativeQueryの使い方と実践例』をご参照ください)
6. JPA・Spring Data JPA・Hibernateの役割を混ぜない
| 名前 | 主な役割 |
|---|---|
| JPA / Jakarta Persistence | 永続化の標準仕様 |
| Spring Data JPA | Repository抽象化などJPA利用を支援するSpring Dataモジュール |
| Hibernate | JPAの代表的な実装の一つ |
エラー調査では、仕様の問題なのか、Spring DataのRepository層なのか、実装プロバイダ固有の挙動なのかを分けて確認すると原因を絞りやすくなります。
よくある質問
Spring Data JPAを使えばEntityManagerは不要ですか?
典型的なCRUDはRepositoryで扱えますが、より低レベルな永続化制御が必要な場面ではEntityManagerを使うことがあります。用途で選びます。
RepositoryにSQLを書かなくても検索できますか?
単純な条件はメソッド名からクエリを導出できます。複雑な条件や明示性が必要な場合は@Queryなどを使います。
まとめ:Repositoryの役割を起点に整理する
- JPAは永続化仕様、Spring Data JPAはその利用を支援する
- Entityは永続化対象と主キーを定義する
- Repository継承で基本CRUDを利用できる
- saveは新規・既存判定でpersist/mergeを使い分ける
- 単純検索はメソッド名、複雑な検索は@Queryを検討する
手元のRepositoryを1つ開き、Entity・主キー型・継承インターフェース・検索メソッドの4点を対応付けて確認してみてください。