【Spring Boot】Spring Data JPAの基本とEntityの定義

Java

こんにちは、かつコーチです。

Spring Bootでデータベースを扱うとき、多くの現場で使われているのがSpring Data JPAです。

「JDBCと何が違うの?」「Entityって結局なに?」というところで止まってしまう人が多いので、今回は基本の考え方とEntityの定義方法を整理していきます。

Spring Data JPAとは

JPAとHibernateの関係

JPA(Java Persistence Association)とは、Javaのオブジェクトとデータベースのテーブルを結びつけるための標準仕様です。

JPA自体は「こういうルールで実装してね」という仕様書のようなもので、実際に処理を行う実装が必要になります。

その実装の代表格がHibernateというライブラリで、Spring Bootでは特に設定しなくてもHibernateが標準で使われます。

Spring Data JPAは、このJPAをさらに使いやすくラップしたSpringのモジュールで、SQLをほとんど書かずにデータベース操作ができるようになります。

なぜSQLを直接書かないのか

JDBCで直接SQLを書く方法もありますが、テーブルの列が増えるたびにSQL文とマッピング処理を手作業で修正する必要があり、ミスが起きやすくなります。

Spring Data JPAでは、Javaのクラス(Entity)とテーブルの対応関係を一度定義しておけば、あとはJavaのメソッド呼び出しだけでデータの読み書きができます。

ORM(Object-Relational Mapping)と呼ばれる、オブジェクトとリレーショナルデータベースを対応付ける仕組みの一種です。

Entityの定義方法

依存関係の追加

まずbuild.gradle(またはpom.xml)にSpring Data JPAとデータベースドライバを追加します。

dependencies {
    implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
    runtimeOnly 'com.mysql:mysql-connector-j'
}

基本のEntityクラス

Entityは、データベースのテーブル1つに対応するJavaクラスです。

package com.example.demo.entity;

import jakarta.persistence.*;

@Entity
@Table(name = "books")
public class Book {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Column(nullable = false, length = 100)
    private String title;

    @Column(name = "author_name")
    private String author;

    private int price;

    // getter/setterは省略
}
  • @Entity:このクラスがJPAの管理対象であることを示す
  • @Table(name = "books"):対応するテーブル名を指定(省略時はクラス名がそのまま使われる)
  • @Id:主キーに対応するフィールドを指定
  • @GeneratedValue:主キーの採番方法を指定(IDENTITYはDB側のAUTO_INCREMENTに任せる方式)
  • @Column:カラムの詳細設定(省略した場合はフィールド名がそのままカラム名になる)

Spring Boot 3.x系ではjavax.persistenceではなくjakarta.persistenceパッケージを使う点に注意してください。

Spring Boot 2系の記事や書籍を参考にするとjavax.persistenceのままインポートしてしまい、依存関係が解決できずにビルドエラーになることがあります。

つまずきやすいポイント

デフォルトコンストラクタの省略

❌ Before:引数ありコンストラクタしか定義しない

@Entity
public class Book {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String title;

    public Book(String title) {
        this.title = title;
    }
}

これを実行すると、Hibernateがデータを取得する際にInstantiationExceptionが発生します。

Hibernateは内部でリフレクションを使い、引数なしのコンストラクタでインスタンスを生成してからフィールドに値を詰めるためです。

✅ After:引数なしコンストラクタを明示的に用意する

@Entity
public class Book {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String title;

    protected Book() {}

    public Book(String title) {
        this.title = title;
    }
}

Lombokの@NoArgsConstructorを使えば、この定型コードを1行で済ませることもできます。

応用・一歩先の使い方

テーブル自動生成の設定

application.propertiesに以下を設定すると、起動時にEntityの定義からテーブルを自動生成してくれます。

spring.jpa.hibernate.ddl-auto=update
spring.jpa.show-sql=true

ddl-auto=updateは開発中は便利ですが、本番環境で使うと意図しないテーブル変更が起きるリスクがあるため、本番ではvalidatenoneに切り替えるのが定石です。

まとめ

この記事のポイント

  • JPAはオブジェクトとテーブルを結びつける標準仕様、Hibernateはその実装
  • @Entity@Id@ColumnでEntityとテーブルの対応関係を定義する
  • Spring Boot 3.x系ではjakarta.persistenceパッケージを使う
  • Entityには引数なしコンストラクタが必須

次に読むべき記事

  • Repositoryインターフェースの基本
  • CRUD操作の実装
  • @OneToMany・@ManyToOneでリレーションを組む

タグ: Spring Boot, 初心者向け, データベース

タイトルとURLをコピーしました