JPA 2.2-Unterstützung für Java 8-Datums- / Uhrzeittypen

1. Übersicht

Die JPA 2.2-Version hat die Unterstützung für die Java 8- API für Datum und Uhrzeit offiziell eingeführt . Zuvor mussten wir uns entweder auf eine proprietäre Lösung verlassen oder die JPA Converter-API verwenden.

In diesem Tutorial zeigen wir, wie die verschiedenen Java 8- Datums- und Uhrzeittypen zugeordnet werden . Wir werden uns besonders auf diejenigen konzentrieren, die die Offset-Informationen berücksichtigen.

2. Maven-Abhängigkeiten

Bevor wir beginnen, müssen wir die JPA 2.2-API in den Projektklassenpfad aufnehmen. In einem Maven-basierten Projekt können wir seine Abhängigkeit einfach zu unserer Datei pom.xml hinzufügen :

 javax.persistence javax.persistence-api 2.2 

Zum Ausführen des Projekts benötigen wir außerdem eine JPA-Implementierung und den JDBC-Treiber der Datenbank, mit der wir arbeiten werden. In diesem Tutorial verwenden wir EclipseLink und die PostgreSQL-Datenbank:

 org.eclipse.persistence eclipselink 2.7.4 runtime   org.postgresql postgresql 42.2.5 runtime bundle 

Sie können die neuesten Versionen der JPA-API, des EclipseLink- und des PostgreSQL-JDBC-Treibers in Maven Central überprüfen.

Natürlich können wir auch andere Datenbanken oder JPA-Implementierungen wie Hibernate verwenden.

3. TimeZone-Unterstützung

Wir können mit jeder Datenbank arbeiten, aber zuerst sollten wir die Unterstützung für diese Standard-SQL-Typen überprüfen, da JDBC 4.2 auf Folgendem basiert:

  • Zeitstempel (n) mit Zeitzone
  • TIMESTAMP (n) OHNE ZEITZONE
  • ZEIT (n) MIT ZEITZONE
  • ZEIT (n) OHNE ZEITZONE

Hier ist n die Sekundenbruchteilgenauigkeit und liegt zwischen 0 und 9 Stellen. OHNE ZEITZONE ist optional und kann weggelassen werden. Wenn WITH TIME ZONE angegeben ist, ist der Name der Zeitzone oder der Versatz zu UTC erforderlich.

Wir können die Zeitzone in einem dieser beiden Formate darstellen:

  • Name der Zeitzone
  • Versatz von UTC oder der Buchstabe Z für UTC

In unserem Beispiel haben wir die PostgreSQL-Datenbank ausgewählt, da sie den SQL-Typ TIME WITH TIME ZONE vollständig unterstützt .

Beachten Sie, dass andere Datenbanken diese Typen möglicherweise nicht unterstützen.

4. Zuordnen von Datumstypen vor Java 8

Vor Java 8 wir die generischen SQL - Typen zur Karte in der Regel hatten TIME, DATE und TIMESTAMP , entweder auf die java.sql. * Klassen java.sql.Time , java.sql.Date, und java.sql.Timestamp, bzw. oder zu java.util Typen java.util.Date und java.util.Calendar .

Lassen Sie uns zunächst sehen, wie die Typen java.sql verwendet werden. Hier definieren wir einfach die Attribute mit java.sql- Typen als Teil einer @ Entity- Klasse:

@Entity public class JPA22DateTimeEntity { private java.sql.Time sqlTime; private java.sql.Date sqlDate; private java.sql.Timestamp sqlTimestamp; // ... }

Während die java.sql- Typen wie alle anderen Typen ohne zusätzliche Zuordnung funktionieren, müssen die java.util- Typen die entsprechenden temporalen Typen angeben.

Dies wird durch die getan @Temporal Annotation , deren Wert Attribut ermöglicht es uns , den entsprechenden JDBC - Typ angeben, die mit TemporalType Aufzählung:

@Temporal(TemporalType.TIME) private java.util.Date utilTime; @Temporal(TemporalType.DATE) private java.util.Date utilDate; @Temporal(TemporalType.TIMESTAMP) private java.util.Date utilTimestamp;

Beachten Sie, dass bei Verwendung von Hibernate als Implementierung die Zuordnung von Kalender zu TIME nicht unterstützt wird .

Ebenso können wir die Calendar- Klasse verwenden:

@Temporal(TemporalType.TIME) private Calendar calendarTime; @Temporal(TemporalType.DATE) private Calendar calendarDate; @Temporal(TemporalType.TIMESTAMP) private Calendar calendarTimestamp;

Keiner dieser Typen unterstützt die Zeitzone oder den Offset. Um mit diesen Informationen umgehen zu können, mussten wir traditionell die UTC-Zeit speichern.

5. Zuordnen von Java 8-Datumstypen

Java 8 hat die Pakete java.time eingeführt , und die JDBC 4.2-API hat Unterstützung für die zusätzlichen SQL-Typen TIMESTAMP WITH TIME ZONE und TIME WITH TIME ZONE hinzugefügt .

Wir können jetzt die JDBC-Typen TIME, DATE und TIMESTAMP den java.time- Typen zuordnen - LocalTime, LocalDate und 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;

Darüber hinaus unterstützen wir die versetzte lokale Zeitzone zu UTC über die Klassen OffsetTime und OffsetDateTime :

@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;

Die entsprechenden zugeordneten Spaltentypen sollten TIME WITH TIME ZONE und TIMESTAMP WITH TIME ZONE sein . Leider unterstützen nicht alle Datenbanken diese beiden Typen.

Wie wir sehen können, unterstützt JPA diese fünf Klassen als Basistypen, und es sind keine zusätzlichen Informationen erforderlich, um zwischen Datums- und / oder Zeitinformationen zu unterscheiden.

Nach dem Speichern einer neuen Instanz unserer Entitätsklasse können wir überprüfen, ob die Daten korrekt eingefügt wurden:

6. Fazit

Vor Java 8 und JPA 2.2 mussten Entwickler normalerweise Datums- / Zeittypen in UTC konvertieren, bevor sie beibehalten wurden. JPA 2.2 unterstützt diese Funktion jetzt sofort, indem der Offset zu UTC unterstützt und die JDBC 4.2-Unterstützung für die Zeitzone genutzt wird.

Den vollständigen Quellcode für diese Beispiele finden Sie auf Github.