11.

【Spring】@GeneratedValueアノテーションとは

編集
この記事の要点
  • @GeneratedValueJPA 主キーの自動採番を指定するアノテーション
  • 戦略は IDENTITY / SEQUENCE / TABLE / AUTO / UUID の 5 種類
  • IDENTITY = MySQL の AUTO_INCREMENT、SEQUENCE = Oracle のシーケンス
  • バッチ INSERT には SEQUENCE + allocationSize が高速
  • Hibernate 6 から UUID 戦略がネイティブサポート

 

基本的な使い方

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

5 つの戦略

戦略動作パフォーマンス主な対応 DB
IDENTITYDB の AUTO_INCREMENT に依存普通(バッチ非対応)MySQL / PostgreSQL / SQL Server
SEQUENCEDB シーケンスを取得高速(allocationSize で連続予約)Oracle / PostgreSQL / DB2 / H2
TABLEカウンタ用テーブルで管理低速(DB ロック)全 DB
AUTOHibernate が DB に応じて選択DB 依存標準
UUIDUUID 自動生成(Hibernate 6+)高速標準

IDENTITY

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

# MySQL: BIGINT AUTO_INCREMENT
# PostgreSQL: BIGSERIAL
# SQL Server: IDENTITY(1,1)

SEQUENCE(推奨:パフォーマンス)

@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "user_seq")
@SequenceGenerator(
    name = "user_seq",
    sequenceName = "user_sequence",
    allocationSize = 50,
    initialValue = 1
)
private Long id;

# DDL
CREATE SEQUENCE user_sequence START WITH 1 INCREMENT BY 50;

# allocationSize: 一度に取得する ID の個数
# 例: 50 にすると 1 回の DB クエリで 50 個の ID を予約
#     50 行 INSERT を 1 回のシーケンス取得で済ませられる

TABLE(最後の手段)

@Id
@GeneratedValue(strategy = GenerationType.TABLE, generator = "user_tab_gen")
@TableGenerator(
    name = "user_tab_gen",
    table = "id_generator",
    pkColumnName = "gen_name",
    valueColumnName = "gen_value",
    pkColumnValue = "user_id",
    allocationSize = 50
)
private Long id;

# 内部的にカウンタテーブルを使う
# - SELECT で現在値取得
# - UPDATE で次の値に
# - DB ロックが発生してパフォーマンス悪い
# - すべての DB で動く利点はあるが、原則使わない

AUTO

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

# Hibernate のバージョンと DB に応じて選択
# Hibernate 4: 多くの場合 SEQUENCE
# Hibernate 5+: DB の AUTO_INCREMENT があれば IDENTITY、なければ SEQUENCE
# 明示しないと意図と違う動作になることがあるので、明示推奨

UUID(Hibernate 6+)

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

# 自動で UUID v4 が生成される
# DB に依存しないため分散システムで衝突なし
# カラム型: VARCHAR(36) または BINARY(16)

# Hibernate 5 で UUID を使いたい場合
@Id
@GeneratedValue(generator = "uuid2")
@GenericGenerator(name = "uuid2", strategy = "org.hibernate.id.UUIDGenerator")
@Column(columnDefinition = "char(36)")
private String id;

パフォーマンス比較

IDENTITY の制限

バッチ INSERT で1 件ずつ ID を取得する必要があり、JdbcBatchSize が効きません:

// 1000 件 INSERT
for (int i = 0; i < 1000; i++) {
    em.persist(new User("name" + i));
}

# IDENTITY: 1000 回の INSERT クエリ(バッチ不可)
# SEQUENCE: シーケンス取得 1000 / allocationSize 回 + INSERT バッチ 1000/jdbc.batch_size 回

大量 INSERT に最適化

# application.properties
spring.jpa.properties.hibernate.jdbc.batch_size=100
spring.jpa.properties.hibernate.order_inserts=true
spring.jpa.properties.hibernate.order_updates=true

# SEQUENCE で allocationSize を大きくする
@SequenceGenerator(name = "user_seq", sequenceName = "user_seq", allocationSize = 100)

カスタム ID 生成

// 独自のジェネレータを実装
public class UserIdGenerator implements IdentifierGenerator {
    @Override
    public Object generate(SharedSessionContractImplementor session, Object obj) {
        // 例: USR-2026-001 形式
        long count = (long) session.createQuery("SELECT COUNT(u) FROM User u").uniqueResult();
        return String.format("USR-%d-%03d", LocalDate.now().getYear(), count + 1);
    }
}

@Id
@GeneratedValue(generator = "user-id-gen")
@GenericGenerator(name = "user-id-gen", strategy = "com.example.UserIdGenerator")
private String id;

戦略選択のフローチャート

  • 分散システム / 衝突回避が必要 → UUID
  • Oracle / PostgreSQL で高速 INSERT → SEQUENCE
  • MySQL でシンプルに使う → IDENTITY
  • カスタムフォーマット ID → 自前ジェネレータ
  • DB が変わる可能性 → AUTO(リスクあり)

関連記事

編集
Post Share
子ページ

子ページはありません

同階層のページ
  1. @After
  2. @Autowired
  3. @Bean
  4. @Before
  5. @Column
  6. @Component
  7. @Configuration
  8. @Controller
  9. @Data
  10. @Entity
  11. @GeneratedValue
  12. @Id
  13. @Modifying
  14. @PathVariable
  15. @PropertySource
  16. @Repository
  17. @RequestBody
  18. @RequestMapping
  19. @ResponseBody
  20. @RestController
  21. @Service
  22. @SpringBootApplication
  23. @Table
  24. @Transactional
  25. @Value