Doma 0.9.10の紹介

いくつかの機能についてはリリース前に紹介してきましたが、まだ紹介しきれていないものをいくつかピックアップ。

aptのエラーをよりわかりやすい場所に

これまで、アノテーションの要素部分のエラーであっても、アノテーションが注釈されたクラスやメソッド部分にエラーを表示していたのですが、ちゃんとエラーの発生元に表示させるようにしました。たとえば、@Updateには、更新に含めたいプロパティを指定できる機能があるのですが、そこにエンティティ中に存在しないプロパティを指定するとこんな感じです。

ポップアップのエラーメッセージはこんな感じ。

ここではincludeを取り上げましたが、excludeも同じ感じ。どちらも文字列配列で指定できます。

Oracleを使っている場合にSQLのログでdate/time/timestampリテラルを使用

DBFluteGoogle GroupでOracleにdate/time/timestampリテラルがあるということを知りました。

関数を使って文字列から変換しないといけないとばかり思っていましたよ。
S2Daoでもよくログ出力されるSQLをそのままSQLのツールにこぴぺして実行したいという要望があったのでRDBMSごとにカスタマイズできるように作ってはいたのですが、これは対応しないわけにはいかないです。ということで、デフォルトでこれらのリテラルを使うようにしました。

たとえば、こんな風に出力されます。

insert into Employee (
  id, 
  name, 
  insertTimestamp, 
  updateTimestamp
) 
values (
  1, 
  'test', 
  timestamp'2009-11-21 16:37:49.296',  -- Oracleで実行した場合はtimestampというキーワードがつく
  null
)

テーブルやカラムのネーミングルールは列挙型の指定に変更

これは仕様変更なのですが、これまで特定のインタフェースの実装クラスを指定してもらっていたところに、こんな感じで列挙型を指定してもらうように変えました。

@Entity(naming = NamingType.SNAKE_UPPER_CASE)
public class Employee {
    ...
}

NamingTypeには次の5つがあります。

  • NONE
  • SNAKE_UPPER_CASE
  • SNAKE_LOWER_CASE
  • UPPER_CASE
  • LOWER_CASE

デフォルトはNONEで、エンティティ名やプロパティ名をそのままテーブル名やカラム名とします(ただし、@Tableや@Columnのname要素が明示されていればそちらが優先)。これまでのデフォルトの挙動と同じように「employeeName」というような名前を「EMPLOYEE_NAME」に変換したい場合はSNAKE_UPPER_CASEを指定してください。

なんで、こんな仕様変更を入れたかというと、特定のインタフェースの実装クラスを指定してもらうより列挙型のほうがaptやEclipseプラグインで圧倒的に扱いやすいからです。aptやEclipseプラグインだと自分が知らない実装クラスをインスタンス化して実行することが大変(特にaptではいろいろ条件を整えないとそれができない)だからです。

この修正で、若干拡張性が落ちたものの、これまで実行時に決めていたテーブル名/カラム名コンパイル時に決まるようになりました。aptで生成されたコードをみればどんな名前になるのか一目瞭然でパフォーマンスも向上したと思います。

HOT deploy対応のSqlFileRepositoryを簡単に書けるようにしました

HOT deployのときにSQLファイルをキャッシュするとSQLファイルを修正してもそれが実際には読み込まれないということが起きます。
そこで、アグレッシブにキャッシュするGreedyCacheSqlFileRepositoryとまったくキャッシュしないNoCacheSqlFileRepositoryを用意しました。こんな感じで、HOT deployのときはNoCacheSqlFileRepositoryを使ってもらえれば常に最新のSQLファイルが取得できます。

public class SqlFileRepositoryProxy extends AbstractSqlFileRepository {

    private final SqlFileRepository greedyCacheSqlFileRepository = new GreedyCacheSqlFileRepository();

    private final SqlFileRepository noCacheSqlFileRepository = new NoCacheSqlFileRepository();

    @Override
    protected SqlFile getSqlFileWithCacheControl(String path, Dialect dialect) {
        if (HotdeployUtil.isHotdeploy()) {
            return noCacheSqlFileRepository.getSqlFile(path, dialect);
        }
        return greedyCacheSqlFileRepository.getSqlFile(path, dialect);
    }

}

SqlFileRepositoryProxyは、ConfigのgetSqlFileRepository()で返すようにしてください。JPetStoreのサンプルが参考になるかも。

Domaにはほかにキャッシュの仕組みはないので、HOT deployではまるのはここくらいだと思います。