LoginSignup
3
2

More than 5 years have passed since last update.

Doma2のエンティティクラスの日付/時刻型について

Last updated at Posted at 2018-05-19

この話題の前提

  • Doma2を使います。
  • Doma-GenでEntityを自動生成します。
  • UTCとは、エポック秒とします。
  • DBのTIMESTAMP型は、UTC(エポック秒)を保管できるものとします。

参考にさせて頂いたサイト

DBのTIMESTAMP型(日付と時刻)を、エンティティクラスでは、どの型で扱うか?

DBのテーブルに、TIMESTAMP型(日付と時刻)があるとき、どの型で扱うべきか迷いました。
ご意見をお願いいたします。

Doma2でサポートしている日付/時刻型

Doma2では、日付/時刻型として、次のリンク先の型をサポートしています。
http://doma.readthedocs.io/ja/stable/basic/#id4

その中で、日付+時刻を扱う場合は、次のいずれかの型になります。
- java.time.LocalDateTime
- java.sql.Timestamp
- java.util.Date

Doma-Genで生成される型

Doma1時代のDoma-Genでは、TIMESTAMP型(日付と時刻)に対応する型は、java.sql.Timestampでした。
http://doma.seasar.org/extension/doma_gen_gen_task.html#EntityConfig

しかし、Doma2のDoma-Genでは、java.time.LocalDateTimeになっています。
http://doma-gen.readthedocs.io/ja/stable/gen/#entityconfig

java.time.LocalDateTimeの問題だと思う点

次のサイトに詳細がありますが、java.time.LocalDateTimeは、日時をUTCで保持するのではなく、タイムゾーン情報を一切含まない日付時刻で保持します。
https://qiita.com/dmikurube/items/15899ec9de643e91497c#javatimelocaldatetime

DBのTIMESTAMP型(日付と時刻)では、日時をUTCで保持するので、java.time.LocalDateTimeで扱ってしまうと、タイムゾーン情報が欠落してしまいます。

ちなみに、PostgreSQLでは、内部的にUTCで保管されています。
https://www.postgresql.jp/document/9.6/html/datatype-datetime.html

java.sql.Timestampを使うのがよい?

java.sql.Timestampは、UTCを保持できるため、タイムゾーンを指定すれば、そのタイムゾーンでの日時が決まります。
つまり、システム内部で日時をUTCで取り回していれば、出力の際には、タイムゾーンを指定して、そのタイムゾーンの日時表現に変換できます。
そういった意味で、java.sql.Timestampを使うのがいいのかなと思います。

対して、java.time.LocalDateTimeの場合は、タイムゾーン情報を一切含まない日付時刻が、どのタイムゾーンの日時表現かを意識して取り扱う必要があります。
例えば、DBも、システムも、日本のタイムゾーンのみのように、1つのタイムゾーンに限定できるのであれば、事が足りるのかもしれません。

Doma-Genで、TIMESTAMP型(日付と時刻)に対応する型を、java.sql.Timestampにする方法

カスタムのGenDialectクラスを用意する。

使用するDBのGenDialectクラス(この例では、PostgreSQLのGenDialectクラス)を継承して、カスタム用のクラスを用意します。

/**
 * PostgreSQL用の方言をカスタマイズするクラス
 */
public class CustomPostgresGenDialect extends PostgresGenDialect {
    public CustomPostgresGenDialect() {
        // タイムゾーン付きのtimestampは、java.sql.Timestampにマッピングする。
        classNameMap.put("timestamptz", Timestamp.class.getName());
    }
}

Doma-Genのトップレベルパラメーターに指定する。

トップレベルのgenDialectClassNameに、上記のクラスを指定して、Doma-Genを実行します。(タスク実行時のクラスパスに、指定したクラスを含める必要があります。)
http://doma-gen.readthedocs.io/ja/stable/gen/#id2

3
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
2