Doma 1.11.0 の新機能

新機能についていくつか紹介。

EntityListenerで削除/挿入/更新の処理後をフック可能

EntityListenerにpostInsert、postUpdate、postDeleteのメソッドを追加しました。これまで処理前しかフックできませんでしたが、処理後もフックできるようになりました。EntityListenerの定義はこのようになっています。

public interface EntityListener<E> {
    void preInsert(E entity, PreInsertContext context);
    void preUpdate(E entity, PreUpdateContext context);
    void preDelete(E entity, PreDeleteContext context);
    void postInsert(E entity, PostInsertContext context);
    void postUpdate(E entity, PostUpdateContext context);
    void postDelete(E entity, PostDeleteContext context);
}

EntityListenerでエンティティに変更があったかどうかをチェック可能

preUpdateメソッドの2番目のパラメータを使って次のように記述することで、エンティティに変更があった場合にのみ処理するといったことが可能です。

public class EmployeeListener implements EntityListener<Employee> {
    ...
    @Override
    public void preUpdate(Employee employee, PreUpdateContext context) {
        if (context.isEntityChanged()) {
            Timestamp timestamp = new Timestamp(System.currentTimeMillis());
            employee.setUpdateTimestamp(timestamp);
        }
    }
    ...
}

PreUpdateContextクラスには、特定のプロパティが変更されたか確かめるisPropertyChanged(String)というメソッドもあります。
注意点としては、上記のようなコードの記述は、エンティティに@OriginalStatesを付与し、エンティティ取得時の状態を保持している場合にのみ本当の意味を成します。ただし、@OriginalStatesを付与していない場合であってもisEntityChanged()やisPropertyChanged(String)は常にtrueを返すので、常に上の例のようにプログラミングするのがお奨めです。

SQLコンパイル時のチェックを強化

バインド変数コメントの直後のテストデータの形式をチェックするようにしました。
たとえば、次のSQLコンパイルにエラーになります。(以前のバージョンでは不正なSQLが組み立てられ、結果としてランタイム時のエラーになっていました)

select * from employee where /* employeeName */employeeName = 'aaa'

正しくは、このようなSQLでなければいけません。

select * from employee where employeeName = /* employeeName */'aaa'

バインド変数コメントの直後が文字列や数値のリテラル(っぽい)かどうかで判定しています。