jpa-java-time
Java 8の日付/時刻型のJPA 2.2サポート
1. 概要
JPA 2.2バージョンでは、https://www.baeldung.com/java-8-date-time-intro [Java 8 _Date_ and _Time_ API]のサポートが正式に導入されました。 その前に、独自のソリューションに依存するか、JPA Converter APIを使用する必要がありました。
このチュートリアルでは、さまざまなJava 8の_Date_および_Time_タイプをマップする方法を示します*。 特に、オフセット情報を考慮するものに焦点を当てます。
2. Mavenの依存関係
開始する前に、JPA 2.2 APIをプロジェクトクラスパスに含める必要があります。 Mavenベースのプロジェクトでは、dependency_pom.xml_ファイルにその依存関係を簡単に追加できます。
<dependency>
<groupId>javax.persistence</groupId>
<artifactId>javax.persistence-api</artifactId>
<version>2.2</version>
</dependency>
さらに、プロジェクトを実行するには、JPA実装と作業するデータベースのJDBCドライバーが必要です。 このチュートリアルでは、EclipseLinkとPostgreSQLデータベースを使用します。
<dependency>
<groupId>org.eclipse.persistence</groupId>
<artifactId>eclipselink</artifactId>
<version>2.7.4-RC1</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<version>42.2.5</version>
<scope>runtime</scope>
<type>bundle</type>
</dependency>
https://search.maven.org/search?q=g:javax.persistence%20AND%20a:javax.persistence-apiの最新バージョンをお気軽にご確認ください
もちろん、他のデータベースまたはHibernateなどのJPA実装を使用できます。
3. TimeZoneのサポート
任意のデータベースで作業できますが、最初に、JDBC 4.2は以下に基づいているため、これらの標準SQLタイプのサポートを確認する必要があります。
-
TIMESTAMP(n)WITH TIME ZONE
-
TIMESTAMP(n)時間帯なし
-
TIME(n)WITH TIME ZONE
-
TIME(n)時間帯なし
ここで、_n_は秒の小数部の精度であり、0〜9桁です。 _WITHOUT TIME ZONE_はオプションであり、省略できます。 _WITH TIME ZONE_が指定されている場合、タイムゾーン名またはUTCへのオフセットが必要です。
次の2つの形式のいずれかでタイムゾーンを表すことができます。
-
タイムゾーン名
-
UTCからのオフセットまたはUTCの文字Z
この例では、SQLタイプ_TIME WITH TIME ZONE_を完全にサポートしているため、PostgreSQLデータベースを選択しました。
他のデータベースはこれらのタイプをサポートしていない可能性があることに注意してください。
*4. Java 8 *より前の日付タイプのマッピング
Java 8より前は、通常、汎用SQL型_TIME、DATE_、および_TIMESTAMP_、を_java.sql。* _ classes _java.sql.Time_、_java.sql.Date、_および_java.sql.Timestampのいずれかにマップする必要がありました。 _それぞれ、または_java.util_型_java.util.Date_および_java.util.Calendar_に。
最初に、_java.sql_型の使用方法を見てみましょう。 ここでは、単に_ @ Entity_クラスの一部として_java.sql_型の属性を定義しています。
@Entity
public class JPA22DateTimeEntity {
private java.sql.Time sqlTime;
private java.sql.Date sqlDate;
private java.sql.Timestamp sqlTimestamp;
// ...
}
-
_java.sql_型は追加のマッピングなしで他の型と同様に機能しますが、_java.util_型は対応する一時的な型を指定する必要があります。*
これは、@ _ TemporalType_ enumerationを使用して、対応するJDBCタイプを指定できる_value_属性を持つ_ @ Temporal_アノテーションによって行われます。
@Temporal(TemporalType.TIME)
private java.util.Date utilTime;
@Temporal(TemporalType.DATE)
private java.util.Date utilDate;
@Temporal(TemporalType.TIMESTAMP)
private java.util.Date utilTimestamp;
Hibernateを実装として使用している場合、_Calendar_から_TIME_へのマッピングはサポートされないことに注意してください。
同様に、_Calendar_クラスを使用できます。
@Temporal(TemporalType.TIME)
private Calendar calendarTime;
@Temporal(TemporalType.DATE)
private Calendar calendarDate;
@Temporal(TemporalType.TIMESTAMP)
private Calendar calendarTimestamp;
これらのタイプはいずれも、タイムゾーンまたはオフセットをサポートしていません。 これらの情報を処理するために、従来はUTC時間を保存する必要がありました。
5. Java 8の日付タイプのマッピング
Java 8は_java.time_パッケージを導入し、JDBC 4.2 APIは追加のSQL型_TIMESTAMP WITH TIME ZONE_および_TIME WITH TIME ZONE_のサポートを追加しました。
-
JDBCタイプ_TIME、DATE、および_TIMESTAMP_を_java.time_タイプにマップできるようになりました*– _LocalTime、 LocalDate、および_LocalDateTime_:
@Column(name = "local_time", columnDefinition = "TIME")
private LocalTime localTime;
@Column(name = "local_date", columnDefinition = "DATE")
private LocalDate localDate;
@Column(name = "local_date_time", columnDefinition = "TIMESTAMP")
private LocalDateTime localDateTime;
さらに、_OffsetTime_および_OffsetDateTime_クラスを介してUTCへのローカルタイムゾーンのオフセットをサポートしています。
@Column(name = "offset_time", columnDefinition = "TIME WITH TIME ZONE")
private OffsetTime offsetTime;
@Column(name = "offset_date_time", columnDefinition = "TIMESTAMP WITH TIME ZONE")
private OffsetDateTime offsetDateTime;
対応するマップされた列タイプは、_TIME WITH TIME ZONE_および_TIMESTAMP WITH TIME ZONE_でなければなりません。 残念ながら、すべてのデータベースがこれら2つのタイプをサポートしているわけではありません。
ご覧のとおり、JPAはこれらの5つのクラスを基本型としてサポートしており、日付と時刻の情報を区別するために追加情報は必要ありません。
エンティティクラスの新しいインスタンスを保存した後、データが正しく挿入されたことを確認できます。
link:/uploads/date_time-100x8.png%20100w []
6. 結論
Java 8およびJPA 2.2より前は、開発者は通常、日付/時刻型を永続化する前にUTCに変換する必要がありました。 JPA 2.2は、UTCへのオフセットをサポートし、タイムゾーンのJDBC 4.2サポートを活用することにより、この機能をすぐにサポートするようになりました。
これらのサンプルの完全なソースコードは、https://github.com/eugenp/tutorials/tree/master/persistence-modules/java-jpa [Github上]にあります。