category: Java
DATE : 2006/11/12 (Sun)
DATE : 2006/11/12 (Sun)
Java Persistence API(JPA)を使用すると、Java Beans とデータベースとを比較的容易に対応付けることができます。
例えば、あるクラスの code プロパティを主キーとして対応付ける場合は、次のようになります(この場合、対応付けられるのはデータベースの code 列になります)。(「...」は省略を表します)
@Id @Column public Integer getId() { ... } public void setId(Integer id) { ... }
また、主キーの値がデータベースによって自動生成される場合は、次のように指定します。
@Id @Column @GeneratedValue public Integer getId() { ... } ...
この GeneratedValue アノテーションには strategy という要素があります。この要素によって、主キーの値の生成方式を指定できます。
現在の Java Persistence API では、以下の方式が定義されています。
- GenerationType.IDENTITY
- データベースが識別番号を生成します。データベースやフレームワークが IDENTITY 型を定義している必要があります。
- GenerationType.SEQUENCE
- データベースが連番を生成します。データベースやフレームワークが連番型を定義している必要があります。
- GenerationType.TABLE
- 連番の状態を特定のテーブルに保存することで、識別番号を生成します。
- GenerationType.AUTO
- Java Persistence API を提供するライブラリやフレームワークが、自動的に方式を判断します。
PostgreSQL では、連番型を表す serial 型が定義されています。そのため、serial 型の主キーにプロパティを対応付ける場合、Generation.SEQUENCE を指定しがちです。
@Id @Column @GeneratedValue(stragegy = GenerationValue.SEQUENCE) public Integer getId() { .... }
しかし実際には、Generation.IDENTITY を指定しなければ正しく動作しません。
@Id @Column @GeneratedValue(stragegy = GenerationValue.IDENTITY) public Integer getId() { ... }
なぜ SEQUENCE ではなく IDENTITY なのかは、勉強不足のため正確なところはわかりません。
ただ、PostgreSQL の連番型は、連番を生成するジェネレータから出力される値が連番であるだけで、主キー列が必ずしも連番になるとは限りません(例えば、トランザクションがアボートされた場合、ジェネレータの連番は元に戻りません。つまり、主キーの連番が1つ空くことになります)。
このあたりが、PostgreSQL の連番型には SEQUENCE ではなく IDENTITY を指定する理由なのではないかと思います。
参考文献
- Using Primary Keys with Java Persistence
- PostgreSQL 8.1.5文書 8.1.4. 連番型
- PostgreSQL 8.1.5文書 9.12. シーケンス操作関数
- Sun Java System Application Server Platform Edition 9 Developer's Guide - 7. Using the Java Persistence API - Database Restrictions and Optimizations - Using a SERIAL Field in PostgreSQL
- Hibernate Forums "ID in abstract class, with entity-specific sequence name" GenerationType.AUTO を指定した場合の方法が書かれています
PR
●この記事にコメントする
忍者ブログ [PR]