UPDATE文に自動で更新タイムスタンプを含める方法(Doma 0.9.10で)

updateの度にプログラムでわざわざタイムスタンプを更新しなくても自動で設定したいという話です。

更新タイムスタンプとかは、複数エンティティで共通でしょうから、共通用のクラスつくります。

@Entity
public class Common {

    Timestamp updateTimestamp;
}

更新系SQLの直前にエンティティに触れるようにするためのEntityListenerというインタフェースがあるのでこの実装を作ります。今回はUPDATE文が発行される前に呼び出されるpreUpdateメソッドでタイムスタンプを設定します。

public class CommonListener implements EntityListener<Common> {
    ...
    @Override
    public void preUpdate(Common entity) {
        entity.updateTimestamp = new Timestamp(System.currentTimeMillis());
    }
}

個々のエンティティクラスではCommonを継承し、@Entityのlistener要素にさっきのCommonListenerを設定。

@Entity(listener = CommonListener.class)
public class Employee extends Common {
    ...
}
@Entity(listener = CommonListener.class)
public class Department extends Common {
    ...
}

ふつうに更新処理を行います。ここではEmployeeエンティティのnameプロパティを更新。

EmployeeDao dao = new EmployeeDaoImpl();
Employee employee = dao.selectById(1);
employee.setName("hoge");

dao.update(employee);

Daoのupdateメソッドを実行するとこんなログが出力されます。

update Employee set updateTimestamp = '2009-11-23 22:49:10.25', name = 'hoge', VERSION = 1 + 1 where id = 1 and VERSION = 1

すぐ上のコードではnameプロパティを更新しただけですが、タイムスタンプもちゃんと更新されているのがわかります。


そもそものはなしですが、上で述べた方法の代わりにDBのトリガーを使うっていう方法がもちろんあります。