2.2.2.2. Declaring column attributes. カラム属性の宣言

<2.2.2. Mapping simple properties | 目次 | 2.2.3. Mapping identifier properties>

プロパティマッピングに使われるカラムは、@Column アノテーションで定義できるよ。デフォルト値を上書きするときに使うよ。詳しくは EJB3 仕様を参照。次のプロパティに使えるよ。

  • 全てのアノテートされていないもの
  • @Basic と一緒に
  • @Version と一緒に
  • @Lob と一緒に
  • @Temporal と一緒に
  • @org.hibernate.annotations.CollectionOfElements と一緒に(Hibernateのみ)
@Entity
public class Flight implements Serializable {
...
@Column(updatable = false, name = "flight_name", nullable = false, length=50)
public String getName() { ... }

name プロパティは、not null で、長さ50で、更新不可の flight_name カラムにマッピングされるよ。

このアノテーションは、普通のプロパティも、@Id、@Version でも使えるよ。

@Column(
    name="columnName";                                (1)
    boolean unique() default false;                   (2)
    boolean nullable() default true;                  (3)
    boolean insertable() default true;                (4)
    boolean updatable() default true;                 (5)
    String columnDefinition() default "";             (6)
    String table() default "";                        (7)
    int length() default 255;                         (8)
    int precision() default 0; // decimal precision   (9)
    int scale() default 0; // decimal scale

(1) name(任意): カラム名(デフォルトはプロパティ名)
(2) unique(任意): ユニーク制約フラグ(デフォルト false)
(3) nullable(任意): null可能フラグ(デフォルト true)
(4) insertable(任意): 挿入可能かどうか(デフォルト true)
(5) updatable(任意): 更新可能かどうか(デフォルト true)
(6) columnDefinition(任意): このカラムの SQL DDL を上書き
(7) table(任意): 対象テーブル(デフォルト Entityのテーブル)
(8) length(任意): カラム長(デフォルト 255)
(9) precision(任意): 精度(デフォルト 0)
(10) scale(任意): スケール(デフォルト 0)

2.2.2.3. Embedded objects (aka components) 埋め込みオブジェクト(所謂 コンポーネント

埋め込みコンポーネントをエンティティの中に定義したり、カラムマッピングを上書きしたりできるよ。コンポーネントクラスは、クラスレベルに @Embeddable アノテーションをつけないといけないよ。特定のエンティティに埋め込みオブジェクトをマッピングするには、関連プロパティに、@Embedded と @AttributeOverride を使うといいよ。

@Entity
public class Person implements Serializable {

    // Persistent component using defaults
    Address homeAddress;

    @Embedded
    @AttributeOverrides( {
            @AttributeOverride(name="iso2", column = @Column(name="bornIso2") ),
            @AttributeOverride(name="name", column = @Column(name="bornCountryName") )
    } )
    Country bornIn;
    ...
}
@Embeddable
public class Address implements Serializable {
    String city;
    Country nationality; //no overriding here
}
@Embeddable
public class Country implements Serializable {
    private String iso2;
    @Column(name="countryName") private String name;

    public String getIso2() { return iso2; }
    public void setIso2(String iso2) { this.iso2 = iso2; }

    
    public String getName() { return name; }
    public void setName(String name) { this.name = name; }
    ...
}

埋め込みオブジェクトは、それを持っているエンティティのアクセスタイプを継承するよ。(Hibernate独自の @AccessType で上書きできるよ。Hibernate Annotation Extensions を見てね。)

Person エンティティBeanは、homeAddress と bornIn の二つのコンポーネントプロパティを持つよ。homeAddress プロパティはアノテートされていないけど、Address クラスの @Embeddable を見て、コンポーネントだと判断されるよ。また、@Embedded と @AttributeOverride アノテーションを使って、Country の カラム名マッピングを bornCountryName に上書きするよ。見たとおり、Country は Address のコンポーネントにもなっていて、自動的にマッピングされるよ。埋め込みオブジェクトの埋め込みオブジェクトのカラムの上書きは、今は EJB3 仕様ではサポートされていないけど、Hibernate Annotations は ドット記法でサポートするよ。

    @Embedded
    @AttributeOverrides( {
            @AttributeOverride(name="city", column = @Column(name="fld_city") ),
            @AttributeOverride(name="nationality.iso2", column = @Column(name="nat_Iso2") ),
            @AttributeOverride(name="nationality.name", column = @Column(name="nat_CountryName") )
            //nationality columns in homeAddress are overridden
    } )
    Address homeAddress;

Hibernate Annotations は EJB3 でサポートされていない機能がもうひとつあるよ。埋め込みオブジェクトに@MappedSuperclass アノテーションを使って、スーパークラスプロパティの永続化ができるよ。(詳しくは @MappedSuperclass を参照。)

EJB3仕様ではサポートされていないけど、Hibernate Annotationsは、埋め込みオブジェクトの関連アノテーション(@*ToOneでも@*ToManyでもなく)を使えるよ。関連カラムの上書きに@AssociationOverrideが使えるよ。

同じエンティティ内で、同じ埋め込みオブジェクトタイプが2回あるなら、デフォルトのカラム名は使えないよ。少なくともひとつのカラムは明示しないとだめだよ。Hibernate は NamingStrategy を使って、デフォルトの名前付けメカニズムを強化することができるよ。DefaultComponentSafeNamingStrategy は、EJB3NamingStrategy を少し改良して、埋め込みオブジェクトを同じエンティティ内で2回使ってもデフォルトで大丈夫なようになってるよ。

2.2.2.4. Non-annotated property defaults. アノテートされていないプロパティのデフォルト

プロパティがアノテートされていないと、次のルールが適用されるよ。

  • プロパティが単一だったら、@Basic としてマッピングされる。
  • それ以外で、プロパティの型が@Embeddableアノテートされていたら、@Embedded としてマッピングされる。
  • それ以外で、プロパティの型が Serializable だったら、カラムが持っているオブジェクトに、@Basic としてマッピングされる。
  • それ以外で、プロパティの型が java.sql.Clob か java.sql.Blob だったら、@Lob としてマッピングされる。

<2.2.2. Mapping simple properties | 目次 | 2.2.3. Mapping identifier properties>