2.2.3. Mapping identifier properties. IDのマッピング*1
<2.2.2.2. Declaring column attributes | 目次 | 2.2.4. Mapping inheritance>
@Id アノテーションはエンティティBeanの識別子を定義するよ。このプロパティはアプリケーションでもセットできるけど、Hibernateで生成させたほうがよいよ。@GeneratedValueアノテーションで生成戦略を定義できるよ。
- AUTO - IDENTITY か SEQUENCE か TABLE を元のDBによって自動につけるよ
- TABLE - IDを持つテーブル
- IDENTITY - IDカラム
- SEQUENCE - シーケンス
Hibernate は EJB3 より多くの IDジェネレータがあるよ。詳細は Hibernate Annotation Extensions を見てね。
次の例では、SEQ_STORE を使ったシーケンスジェネレータを示すよ。
@Id @GeneratedValue(strategy=GenerationType.SEQUENCE, generator="SEQ_STORE") public Integer getId() { ... }
次の例は IDENTITY ジェネレータだよ。
@Id @GeneratedValue(strategy=GenerationType.IDENTITY) public Long getId() { ... }
AUTOジェネレータは、アプリケーションの移植性がよいよ。ID生成の設定は共通化できるよ。@SequenceGenerator、@TableGenerator を使ったいろんな設定があるよ。ジェネレータの範囲はアプリケーション全体か、クラス毎ができるよ。クラス定義ジェネレータは、クラスの外から見えなくて、アプリケーションレベルのジェネレータを上書きできるよ。アプリケーションレベルのジェネレータはXMLレベルで設定するよ。(Chapter Overriding metadata through XML, Overriding metadata through XML を参照)
<table-generator name="EMP_GEN" table="GENERATOR_TABLE" pk-column-name="key" value-column-name="hi" pk-column-value="EMP" allocation-size="20"/> //and the annotation equivalent @javax.persistence.TableGenerator( name="EMP_GEN", table="GENERATOR_TABLE", pkColumnName = "key", valueColumnName = "hi" pkColumnValue="EMP", allocationSize=20 ) <sequence-generator name="SEQ_GEN" sequence-name="my_sequence" allocation-size="20"/> //and the annotation equivalent @javax.persistence.SequenceGenerator( name="SEQ_GEN", sequenceName="my_sequence", allocationSize=20 )
ジェネレータの定義に JPA XML(META-INF/orm/xmlのような)が使われると、EMP_GEN と SEQ_GEN はアプリケーションレベルになるよ。EMP_GEN は
max_lo 20*1 の Hiloアルゴリズムを使った、テーブルベースのIDジェネレータだよ。hi値は GENERATOR_TABLE に保存されるよ。pkColumnName "key" が等しい pkColumnValue "EMP" の行へ情報が保存されて、valueColumnName "hi" は次に高い使われる値を持っているよ。*2
SEQ_GEN は my_sequence という名前のシーケンスを使ったジェネレータだよ。hiloアルゴリズムをベースとしたこのシーケンスで使われるアロケーションサイズは20だよ。このバージョンのHibernate Annotationsでは、シーケンスジェネレータの initialValue は扱わないよ。デフォルトのアロケーションサイズは50だから、もし、シーケンスを使って毎回値をピックアップしたいなら、アロケーションサイズを1にしてね。
- 注意
- パッケージレベルの定義は EJB3.0 仕様では定義されてないけど、パッケージレベルに @GenericGenerator が使えるよ(Section 2.4.Identifier, “Identifier”を見てね)。
次の例は、クラス範囲のシーケンスジェネレータの定義だよ。
@Entity @javax.persistence.SequenceGenerator( name="SEQ_STORE", sequenceName="my_sequence" ) public class Store implements Serializable { private Long id; @Id @GeneratedValue(strategy=GenerationType.SEQUENCE, generator="SEQ_STORE") public Long getId() { return id; } }
このクラスは my_sequence という名前のシーケンスを使って、SEQ_STOREジェネレータは他のクラスからは見えないよ。org.hibernate.test.annotations.id パッケージの テストにもっと例があるよ。
いくつかの記法で、複合主キーを定義できるよ。
- コンポーネントプロパティを @Id にして、コンポーネントクラスを @Embeddable にする
- コンポーネントプロパティに @EmbeddadId をつける
- クラスを @IdClass にして、複合主キーのプロパティに @Id をつける
@IdClass は、EJB2 を使った人なら知ってるけど、Hibernate ユーザには初めてかもしれないね。複合主キークラスは、エンティティクラスのフィールドやプロパティとつながっていて、名前も型も同じでないといけないよ。次の例を見て!
@Entity @IdClass(FootballerPk.class) public class Footballer { //part of the id key @Id public String getFirstname() { return firstname; } public void setFirstname(String firstname) { this.firstname = firstname; } //part of the id key @Id public String getLastname() { return lastname; } public void setLastname(String lastname) { this.lastname = lastname; } public String getClub() { return club; } public void setClub(String club) { this.club = club; } //appropriate equals() and hashCode() implementation } @Embeddable public class FootballerPk implements Serializable { //same name and type as in Footballer public String getFirstname() { return firstname; } public void setFirstname(String firstname) { this.firstname = firstname; } //same name and type as in Footballer public String getLastname() { return lastname; } public void setLastname(String lastname) { this.lastname = lastname; } //appropriate equals() and hashCode() implementation }
見ての通り、@IdClass は対応する主キークラスを指すよ。
EJB3仕様ではサポートされないけど、Hibernateでは複合主キーの関連を定義できるよ。簡単に使い方を示すよ。
@Entity @AssociationOverride( name="id.channel", joinColumns = @JoinColumn(name="chan_id") ) public class TvMagazin { @EmbeddedId public TvMagazinPk id; @Temporal(TemporalType.TIME) Date time; } @Embeddable public class TvMagazinPk implements Serializable { @ManyToOne public Channel channel; public String name; @ManyToOne public Presenter presenter; }
<2.2.2.2. Declaring column attributes | 目次 | 2.2.4. Mapping inheritance>