JPA 2.2-ondersteuning voor Java 8 datum- / tijdtypen
1. Overzicht
De JPA 2.2-versie heeft officieel de ondersteuning voor Java 8 geïntroduceerd Datum en Tijd API. Voordien moesten we ofwel vertrouwen op een eigen oplossing, ofwel moesten we de JPA Converter API gebruiken.
In deze tutorial we laten zien hoe je de verschillende Java 8 in kaart kunt brengen Datum en Tijd types. We zullen ons vooral concentreren op degenen die rekening houden met de offset-informatie.
2. Maven afhankelijkheden
Voordat we beginnen, moeten we de JPA 2.2 API opnemen in het klassenpad van het project. In een op Maven gebaseerd project kunnen we eenvoudig de afhankelijkheid ervan toevoegen aan onze pom.xml het dossier:
javax.persistence javax.persistence-api 2.2
Bovendien hebben we om het project uit te voeren een JPA-implementatie nodig en het JDBC-stuurprogramma van de database waarmee we zullen werken. In deze tutorial gebruiken we EclipseLink en de PostgreSQL-database:
org.eclipse.persistence eclipselink 2.7.4 runtime org.postgresql postgresql 42.2.5 runtime-bundel
Bekijk gerust de nieuwste versies van JPA API, EclipseLink en PostgreSQL JDBC-stuurprogramma op Maven Central.
Natuurlijk kunnen we andere databases of JPA-implementaties gebruiken, zoals Hibernate.
3. TimeZone-ondersteuning
We kunnen met elke database werken, maar eerst moeten we de ondersteuning voor deze standaard SQL-typen controleren, aangezien JDBC 4.2 is gebaseerd op:
- TIMESTAMP (n) MET TIJDZONE
- TIMESTAMP (n) ZONDER TIJDZONE
- TIJD (n) MET TIJDZONE
- TIJD (n) ZONDER TIJDZONE
Hier, n is de precisie van een fractie van een seconde en is tussen 0 en 9 cijfers. ZONDER TIJDZONE is optioneel en kan worden weggelaten. Als MET TIJDZONE is opgegeven, is de naam van de tijdzone of de offset naar UTC vereist.
We kunnen de tijdzone weergeven in een van deze twee formaten:
- Tijdzone naam
- Verschuiving ten opzichte van UTC of de letter Z voor UTC
Voor ons voorbeeld hebben we gekozen voor de PostgreSQL-database dankzij de volledige ondersteuning voor het SQL-type TIJD MET TIJDZONE.
Houd er rekening mee dat andere databases deze typen mogelijk niet ondersteunen.
4. Datatypes in kaart brengen vóór Java 8
Vóór Java 8 moesten we meestal de generieke SQL-typen in kaart brengen TIJD DATUM, en TIJDSTAMP, naar ofwel de java.sql. * klassen java.sql.Time, java.sql.Datum, en java.sql.Timestamp, respectievelijk, of naar java.util types java.util.Date en java.util.Calendar.
Laten we eerst eens kijken hoe we het java.sql types. Hier definiëren we eenvoudig de attributen met java.sql typen als onderdeel van een @Entiteit klasse:
@Entity openbare klasse JPA22DateTimeEntity {privé java.sql.Time sqlTime; privé java.sql.Date sqlDate; privé java.sql.Timestamp sqlTimestamp; // ...}
Terwijl de java.sql typen werken net als alle andere typen zonder enige extra toewijzing, de java.util types moeten de corresponderende temporele types specificeren.
Dit gebeurt via de @Tijdelijk annotatie waarvan waarde attribuut stelt ons in staat het corresponderende JDBC-type te specificeren met behulp van de TemporalType opsomming:
@Temporal (TemporalType.TIME) privé java.util.Date utilTime; @Temporal (TemporalType.DATE) privé java.util.Date utilDate; @Temporal (TemporalType.TIMESTAMP) privé java.util.Date utilTimestamp;
Merk op dat als we Hibernate als implementatie gebruiken, dit geen ondersteuning biedt voor mapping Kalender naar TIJD.
Evenzo kunnen we de Kalender klasse:
@Temporal (TemporalType.TIME) privé Kalender calendarTime; @Temporal (TemporalType.DATE) privé Kalender calendarDate; @Temporal (TemporalType.TIMESTAMP) privé Kalender calendarTimestamp;
Geen van deze typen ondersteunt de tijdzone of de offset. Om met die stukjes informatie om te gaan, moesten we traditioneel de UTC-tijd opslaan.
5. In kaart brengen van Java 8-datatypes
Java 8 heeft de java.time pakketten, en de JDBC 4.2 API toegevoegde ondersteuning voor de aanvullende SQL-typen TIJDSTEMPEL MET TIJDZONE en TIJD MET TIJDZONE.
We kunnen nu de JDBC-typen in kaart brengen TIJD DATUM, en TIJDSTAMP naar de java.time types – Lokale tijd,LocalDate, en LocalDateTime:
@Column (name = "local_time", columnDefinition = "TIME") private LocalTime localTime; @Column (name = "local_date", columnDefinition = "DATE") privé LocalDate localDate; @Column (name = "local_date_time", columnDefinition = "TIMESTAMP") privé LocalDateTime localDateTime;
Bovendien hebben we ondersteuning voor de offset lokale tijdzone naar UTC via de OffsetTime en OffsetDateTime klassen:
@Column (name = "offset_time", columnDefinition = "TIJD MET TIJDZONE") privé OffsetTime offsetTime; @Column (name = "offset_date_time", columnDefinition = "TIMESTAMP MET TIJDZONE") private OffsetDateTime offsetDateTime;
De corresponderende toegewezen kolomtypen zouden TIJD MET TIJDZONE en TIJDSTEMPEL MET TIJDZONE. Helaas ondersteunen niet alle databases deze twee typen.
Zoals we kunnen zien, ondersteunt JPA deze vijf klassen als basistypen en is er geen aanvullende informatie nodig om onderscheid te maken tussen de datum- en / of tijdinformatie.
Nadat we een nieuw exemplaar van onze entiteitsklasse hebben opgeslagen, kunnen we controleren of de gegevens correct zijn ingevoegd:

6. Conclusie
Vóór Java 8 en JPA 2.2 moesten ontwikkelaars meestal datum- / tijdtypen naar UTC converteren voordat ze werden gehandhaafd. JPA 2.2 ondersteunt deze functie nu uit de doos door de offset naar UTC te ondersteunen en door gebruik te maken van JDBC 4.2-ondersteuning voor de tijdzone.
De volledige broncode voor deze voorbeelden is te vinden op Github.