カテゴリ: Spring 更新日: 2026/01/05

Springの@GeneratedValueアノテーションを徹底解説!初心者でもわかる自動ID生成の使い方

Springの@GeneratedValueアノテーション
Springの@GeneratedValueアノテーション

先生と生徒の会話形式で理解しよう

生徒

「JavaのSpringでデータベースにレコードを保存するとき、自動的にIDを生成してくれる方法があるって聞いたんですが、どうやるんですか?」

先生

「良い質問ですね。Springでは@GeneratedValueアノテーションを使うことで、データベースにレコードを保存する際にIDを自動で生成することができます。」

生徒

「それってどういう仕組みなんでしょうか?」

先生

「簡単ですよ。それでは、@GeneratedValueの基本的な使い方を説明しますね!」

1. @GeneratedValueアノテーションとは?

1. @GeneratedValueアノテーションとは?
1. @GeneratedValueアノテーションとは?

@GeneratedValueアノテーションは、JavaのSpringフレームワークにおいて、データベースに新しいレコードを挿入する際に自動でIDを生成するためのものです。 通常、エンティティクラスのプライマリーキー(@Id)に一緒に指定されます。これにより、IDを手動で設定せずに、データベースが自動的に一意なIDを割り振ってくれます。

例えば、ユーザー情報を管理するアプリケーションでは、各ユーザーのIDを自動的に生成してくれるため、毎回自分でユニークなIDを設定する必要がありません。

2. @GeneratedValueの基本的な使い方

2. @GeneratedValueの基本的な使い方
2. @GeneratedValueの基本的な使い方

それでは、@GeneratedValueを使った基本的な例を見ていきましょう。


import jakarta.persistence.Entity;
import jakarta.persistence.Id;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;

@Entity
public class User {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String name;
    private String email;

    public User() {}

    public User(String name, String email) {
        this.name = name;
        this.email = email;
    }

    public Long getId() {
        return id;
    }

    public String getName() {
        return name;
    }

    public String getEmail() {
        return email;
    }
}

この例では、@Id@GeneratedValueを組み合わせてidフィールドに自動でIDを設定しています。 GenerationType.IDENTITYを指定することで、データベースが自動的に連番のIDを生成してくれます。

3. GenerationTypeの種類

3. GenerationTypeの種類
3. GenerationTypeの種類

Springの@GeneratedValueにはいくつかの生成戦略(GenerationType)があります。主な4つのタイプについて解説します。

  • GenerationType.IDENTITY: データベースに任せてIDを自動生成します。主にMySQLで使用されます。
  • GenerationType.SEQUENCE: データベースシーケンスを使用してIDを生成します。主にPostgreSQLやOracleで使われます。
  • GenerationType.TABLE: 専用のテーブルを利用してIDを管理します。全てのDBで使用可能ですが、パフォーマンスが低下する可能性があります。
  • GenerationType.AUTO: データベースに応じて自動で最適な戦略を選択します。

4. @GeneratedValueとfindAllの活用例

4. @GeneratedValueとfindAllの活用例
4. @GeneratedValueとfindAllの活用例

次に、@GeneratedValueで自動生成されたIDを活用して、複数のユーザーを検索する例を見てみましょう。


import org.springframework.data.jpa.repository.JpaRepository;
import java.util.List;

public interface UserRepository extends JpaRepository<User, Long> {
    List<User> findByName(String name);
}

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.stereotype.Component;

@Component
public class UserDataRunner implements CommandLineRunner {

    @Autowired
    private UserRepository userRepository;

    @Override
    public void run(String... args) {
        userRepository.save(new User("Alice", "alice@example.com"));
        userRepository.save(new User("Bob", "bob@example.com"));
        
        List<User> users = userRepository.findByName("Alice");
        users.forEach(user -> System.out.println(user.getName() + " - " + user.getEmail()));
    }
}

Alice - alice@example.com

ここでは、findByNameメソッドを利用して、名前が"Alice"のユーザーを検索しています。@GeneratedValueによってIDは自動生成されており、ユーザー登録時にIDを気にする必要がありません。

5. @GeneratedValueの注意点とベストプラクティス

5. @GeneratedValueの注意点とベストプラクティス
5. @GeneratedValueの注意点とベストプラクティス

@GeneratedValueを使用する際には、いくつかの注意点があります。

  • 主キーの@Idは一度設定すると変更が難しいため、しっかり設計してから使用しましょう。
  • シーケンス戦略(GenerationType.SEQUENCE)は、パフォーマンスに優れますが、DBの設定が必要です。
  • 必要以上にGenerationType.TABLEを使用しないようにしましょう。パフォーマンス低下の原因になります。

6. Spring Bootでの実践的な使用例

6. Spring Bootでの実践的な使用例
6. Spring Bootでの実践的な使用例

Spring Bootでは、@GeneratedValueを活用することで簡単にデータベースと連携したアプリケーションを構築できます。 例えば、ユーザー登録フォームから入力されたデータをそのままデータベースに保存し、自動でIDを割り当てることが可能です。


@RestController
@RequestMapping("/api/users")
public class UserController {
    @Autowired
    private UserRepository userRepository;

    @PostMapping
    public User createUser(@RequestBody User user) {
        return userRepository.save(user);
    }
}

このように、簡単にAPIエンドポイントを作成してユーザーのデータを保存できます。IDは@GeneratedValueで自動生成されます。

7. SEQUENCE戦略の設定(@SequenceGeneratorの使い方)

7. SEQUENCE戦略の設定(@SequenceGeneratorの使い方)
7. SEQUENCE戦略の設定(@SequenceGeneratorの使い方)

GenerationType.SEQUENCEは、データベースのシーケンスからIDを取得する方式です。PostgreSQLやOracleでの利用が一般的で、事前にIDを確保できるためバッチ挿入と相性が良いのが特徴です。 代表的な設定例を見てみましょう。


import jakarta.persistence.*;

@Entity
@SequenceGenerator(
    name = "user_seq",
    sequenceName = "user_id_seq", // DB上のシーケンス名
    allocationSize = 50           // まとめ取りしてパフォーマンス向上
)
public class User {
    @Id
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "user_seq")
    private Long id;

    private String name;
    private String email;
    // getter/setter など
}

PostgreSQLのシーケンス作成例(既存DBに合わせて名称を変更してください):


CREATE SEQUENCE user_id_seq START 1 INCREMENT 1 CACHE 50;
  • allocationSizeはアプリ側でIDを先取りする単位です。大きくすると書き込みが高速化しやすい反面、アプリ停止時に欠番が増えます。
  • 既存のシーケンス名に合わせる場合はsequenceNameだけ合わせればOKです。
  • スキーマを分けている場合はsequenceNameに完全修飾名(例:public.user_id_seq)を指定します。

8. IDENTITYとSEQUENCEの違いと選び方

8. IDENTITYとSEQUENCEの違いと選び方
8. IDENTITYとSEQUENCEの違いと選び方

どの戦略を選ぶかは、使うデータベースと書き込みパターンで決めるのがコツです。主な違いを表で整理します。

項目IDENTITY(自動採番)SEQUENCE(シーケンス)
ID取得タイミングINSERT後にDBが採番INSERT前にアプリが先取り可能
バッチ挿入やや不利(INSERTごとに確定が必要)有利(まとめ取りで高速化しやすい)
向いているDBMySQL、SQL ServerなどPostgreSQL、Oracleなど
欠番の発生障害時に発生しうるallocationSize次第で発生(大きいほど欠番増)
設定の手間少ない(設定ほぼ不要)シーケンス作成や名称合わせが必要
  • MySQL中心ならまずはIDENTITYでシンプルに。
  • 大量の一括登録高スループットが必要ならSEQUENCEallocationSizeの調整が有効。
  • AUTOはDBごとに最適を選びますが、挙動を明確にしたいときは戦略を明示しましょう。

9. よくあるエラーと対処法(トラブルシューティング)

9. よくあるエラーと対処法(トラブルシューティング)
9. よくあるエラーと対処法(トラブルシューティング)
  • 「ids for this class must be manually assigned before calling persist」
    原因:@Idはあるが@GeneratedValueが無い、または手動設定が必要な戦略にしている。
    対処:@GeneratedValueを付ける/適切な戦略に変更する/手動採番なら保存前にIDをセット。
  • 「Table 'hibernate_sequence' doesn't exist」やシーケンス未定義エラー
    原因:SEQUENCE相当の戦略なのに、対応するシーケンス(または擬似シーケンステーブル)がDBに無い。
    対処:利用DBに合わせてシーケンスを作成するか、MySQL中心ならIDENTITYへ切り替える。スキーマ名の食い違いにも注意。
  • バッチ挿入が効かない/遅い(IDENTITY使用時)
    原因:IDENTITYは1行ごとにID確定が必要で、JDBCバッチ最適化が効きにくい。
    対処:SEQUENCEに切り替え、allocationSizeを大きめにする。合わせて以下プロパティの有効化を検討:
    
    spring.jpa.properties.hibernate.jdbc.batch_size=50
    spring.jpa.properties.hibernate.order_inserts=true
    spring.jpa.properties.hibernate.order_updates=true
    
  • 欠番が気になる(SEQUENCE使用時)
    原因:allocationSizeで先取りしたIDが未使用のまま終了すると欠番が増える。
    対処:要件に合わせてallocationSizeを調整。欠番自体は動作上の問題ではないことが多い。

まとめ

まとめ
まとめ

今回の記事では、JavaのSpringフレームワークにおける@GeneratedValueアノテーションについて詳しく解説しました。@GeneratedValueを活用することで、データベースにレコードを保存する際に、自動的に一意のIDを生成できるため、特にプライマリーキーの管理が非常に楽になります。 これにより、IDの重複を防ぎ、データベース操作の効率を高めることができます。

また、GenerationTypeにはいくつかの戦略があり、それぞれの用途に応じて最適なものを選択することが重要です。例えば、MySQLではGenerationType.IDENTITYが一般的に使用されますが、PostgreSQLではGenerationType.SEQUENCEが推奨されます。これらの設定を正しく理解することで、パフォーマンスを向上させ、よりスムーズなアプリケーションの開発が可能になります。

実際の開発現場では、@GeneratedValueとSpring Data JPAのリポジトリ機能を組み合わせることで、簡単にCRUD操作を実現できます。特に、APIのエンドポイントを作成してデータの登録や検索を行う際には、@GeneratedValueの自動ID生成が役立ちます。

先生と生徒の振り返り会話

生徒

「今日学んだ@GeneratedValueアノテーションは、実際にどんな場面で使うんでしょうか?」

先生

「例えば、ユーザー登録を行うWebアプリケーションを作るときに使いますよ。データベースに新しいユーザーを追加する際、自動的にユニークなIDを生成してくれるので、IDの重複を防いでくれます。」

生徒

GenerationType.IDENTITYとかGenerationType.SEQUENCEって何が違うんですか?」

先生

「良い質問です。GenerationType.IDENTITYはデータベースに任せてIDを連番で生成する方法で、MySQLなどでよく使われます。GenerationType.SEQUENCEは専用のシーケンスオブジェクトを利用してIDを生成する方法で、PostgreSQLやOracleでよく使われます。それぞれのデータベースに最適な方法を選ぶことが大事ですね。」

生徒

「なるほど!これでID管理がもっと楽になりそうです。」

先生

「その通りです。ぜひ@GeneratedValueを使って、効率的なデータベース管理に役立ててください。」

【サンプルプログラムの振り返り】

ここでは、再度@GeneratedValueを使ったサンプルプログラムを見ておきましょう。Spring Bootプロジェクトでの実装例です。


@RestController
@RequestMapping("/api/users")
public class UserController {
    @Autowired
    private UserRepository userRepository;

    @PostMapping
    public User createUser(@RequestBody User user) {
        return userRepository.save(user);
    }

    @GetMapping
    public List<User> getAllUsers() {
        return userRepository.findAll();
    }
}

import jakarta.persistence.Entity;
import jakarta.persistence.Id;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;

@Entity
public class User {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String name;
    private String email;

    public User() {}

    public User(String name, String email) {
        this.name = name;
        this.email = email;
    }

    public Long getId() {
        return id;
    }

    public String getName() {
        return name;
    }

    public String getEmail() {
        return email;
    }
}

ここでは、@GeneratedValueアノテーションにより、ユーザーIDが自動で生成される仕組みを再確認しました。このように、Spring Bootではデータベースとの連携が非常にスムーズに行えます。 特に、エンティティとリポジトリの組み合わせで簡単にAPIを構築できる点が魅力です。

この記事を読んだ人からの質問

この記事を読んだ人からの質問
この記事を読んだ人からの質問

プログラミング初心者からのよくある疑問/質問を解決します

@GeneratedValueアノテーションとは何ですか?

@GeneratedValueアノテーションは、Springフレームワークでデータベースにレコードを保存する際に、一意のIDを自動生成するために使用されます。エンティティクラスのプライマリキーに指定するのが一般的です。

@GeneratedValueを使うメリットは何ですか?

手動でIDを管理する必要がなくなり、データベースが自動的に一意なIDを生成します。これにより、IDの重複を防ぎ、効率的にデータを管理できます。

GenerationType.IDENTITYとGenerationType.SEQUENCEの違いは何ですか?

GenerationType.IDENTITYはデータベースに連番のID生成を任せます。一方、GenerationType.SEQUENCEはデータベース内のシーケンスを使用してIDを生成します。PostgreSQLやOracleではSEQUENCEがよく使われます。

GenerationType.AUTOを使うとどうなりますか?

GenerationType.AUTOは、データベースに最適なID生成戦略を自動的に選択します。環境によって使用される戦略が異なるため、特定のDBに依存しない場合に便利です。

@GeneratedValueはどんな場面で使われますか?

主にデータベースの主キー(プライマリキー)を自動生成する場面で使用されます。例えば、ユーザー登録や商品情報の管理など、IDの一意性が重要なアプリケーションで役立ちます。

@GeneratedValueを使用する際の注意点は何ですか?

主キーの値は一度設定されると変更できないため、適切に設計することが重要です。また、GenerationType.TABLEはパフォーマンスに影響する場合があるため、慎重に使用しましょう。

findAllやfindByNameといったSpring Data JPAの機能と組み合わせると何が便利ですか?

Spring Data JPAのリポジトリ機能を使うことで、@GeneratedValueで自動生成されたIDを簡単に検索条件に組み込めます。findAllやfindByNameで効率的なデータ検索が可能です。

Spring Bootでの@GeneratedValueの実装例を教えてください。

Spring Bootでは、@GeneratedValueをエンティティに設定し、コントローラーとリポジトリを通じてデータを保存できます。例えば、@PostMappingを使ったAPIで自動ID生成を活用できます。

@GeneratedValueとAPIエンドポイントの組み合わせ例は?

ユーザー登録APIのエンドポイントで、@GeneratedValueを使ってIDを自動生成し、データベースに保存できます。このように、自動ID生成はバックエンドAPIの開発で非常に便利です。

@GeneratedValueの生成戦略はどのように選べばいいですか?

データベースの種類や用途に応じて選ぶのが最適です。MySQLではGenerationType.IDENTITY、PostgreSQLではGenerationType.SEQUENCEが一般的に使用されます。

@SequenceGeneratorのallocationSizeはどのくらいに設定すべきですか?

書き込み頻度が高いなら50〜100程度から試すのが一般的です。大きくすると挿入は高速化しやすい反面、アプリ停止時の欠番は増えます。要件に合わせて負荷試験で最適値を決めましょう。

sequenceNameにスキーマ名は付けたほうが良いですか?

複数スキーマを使う場合やデフォルトスキーマが環境ごとに異なる場合は、public.user_id_seqのように完全修飾名を指定すると名前解決のミスを防げます。

Springの学習を効率化したい方へ

この記事の内容をもっと深く知るには、以下の入門書が最適です。

Spring Framework超入門をAmazonで見る
カテゴリの一覧へ
新着記事
New1
Spring
SpringDataJPAのJPAクエリメソッド「NotLike」の使い方を完全ガイド!初心者向け解説
更新記事
New2
Spring
SpringDataJPAのJPAクエリメソッド「Like」の使い方を完全ガイド!初心者向け解説
更新記事
New3
Java
JavaのLocalDateTimeクラスとplusMinutesメソッドを完全ガイド!初心者でもわかる分単位の時間操作
新規投稿
New4
Spring
SpringDataJPAのJPAクエリメソッド「IsNotNull」と「NotNull」の使い方を完全ガイド!初心者向け解説
更新記事
人気記事
No.1
Java&Spring記事人気No1
Spring
Spring BootとJavaの互換性一覧!3.5/3.4/3.3はJava 21・17に対応してる?
No.2
Java&Spring記事人気No2
Java
JavaのBooleanクラスの使い方を完全ガイド!初心者でもわかる真偽値の操作
No.3
Java&Spring記事人気No3
JSP
JSPの基本タグ一覧と使い方まとめ!実務で使えるタグを紹介
No.4
Java&Spring記事人気No4
Java
JavaのIOExceptionクラス徹底解説!初心者向けファイル入出力エラー対策ガイド
No.5
Java&Spring記事人気No5
JSP
JSPでif文・for文を使う方法!初心者でもわかるJavaとの違いと使い方
No.6
Java&Spring記事人気No6
Spring
SpringのBindingResultを完全ガイド!初心者でもわかる入力チェックとエラー処理
No.7
Java&Spring記事人気No7
Spring
SpringのModelクラスとaddAttributeメソッドの使い方を完全ガイド!初心者でも安心
No.8
Java&Spring記事人気No8
Spring
SpringDataJPAのJPAクエリメソッド「EndingWith」の使い方を完全ガイド!初心者向け解説