2016年2月19日金曜日

HibernateのColumnDefaultを使ってデフォルト値をDBへ登録する

Hibernateの独自実装のColumnDefaultアノテーションとGeneratedアノテーションを使うと、テーブルへのレコード追加時や更新時にデフォルト値を設定することができる。

ColumnDefaultアノテーション

このアノテーションに設定した値が、デフォルト値となる。
受け取れる値は文字列のみなので、数値型や日付型などのカラムでもすべて文字列で設定する必要がある。

Generatedアノテーション

このアノテーションで初期値を代入するタイミングを定義する。

Entityクラス

lastModified属性が、デフォルト値が代入されるカラムとなる。
ポイントは、Columnアノテーションのinsertableとupdatableにfalseを設定しているところ。
これを行わないと、insertやupdate時にデフォルト値が設定されなくなる。

ColumnDefaultアノテーションは、すでにデータベース上に作成されているテーブルに定義されていることを想定しているので、ここでは使用していない
@Entity
public class HogeEntity {

    @Id
    @GeneratedValue
    public Long id;

    @Column(insertable = false, updatable = false)
    @Generated(GenerationTime.ALWAYS)
    public Timestamp lastModified;

    @Override
    public String toString() {
        return "HogeEntity{" +
                "id=" + id +
                ", lastModified=" + lastModified +
                '}';
    }
}

Entityに対応したテーブル定義

lastModifiedカラムは、登録・更新時にデフォルト値がセットされる。
CREATE TABLE `HogeEntity` (
  `id` bigint(20) NOT NULL,
  `lastModified` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  `name` varchar(255) DEFAULT NULL,
  PRIMARY KEY (`id`)
)

実行結果

Entityをデータベースに永続化する部分の実装例。
HogeEntity entity = new HogeEntity()
em.persist(entity)
em.flush()
System.out.println("entity = " + entity)
上のコードを実行した結果は、このようになる。
明示的にEntityに値を設定していないのに、最終更新日が登録されている。
entity = HogeEntity{id=1, lastModified=2015-12-13 01:29:35.981}

この機能は、既存のテーブルに対してHibernateを適用する際に使用する。
新規に構築する場合には、PrePersistアノテーションを使ってEntityでデフォルト値を設定するのがいいのではないかと思う。