Ich verwende Java 8 für mein neues Projekt.
Ich versuche, die neue Datums- und Uhrzeit-API in Java 8 zu verwenden. Ich weiß jedoch nicht, ob JPA 2.1
diese neue Datums- und Uhrzeit-API vollständig unterstützt.
Teilen Sie bitte Ihre Erfahrungen/Ansichten mit der Unterstützung von JPA für neue Datums- und Zeit-API in Java 8 mit.
Kann ich neue Datums- und Uhrzeit-API in Java 8 sicher mit JPA 2.1 verwenden?
UPDATE:
Ich verwende Hibernate (4.3.5.Final) als JPA-Implementierung.
JPA 2.1 ist eine Spezifikation, die vor Java 1.8 herausgegeben wurde, daher ist keine Unterstützung dafür erforderlich. Offensichtlich unterstützen einige Implementierungen einige Java 1.8-Funktionen. Einige haben Probleme mit dem Java 1.8-Bytecode (z. B. EclipseLink). Ich weiß, dass DataNucleus Java.time und Java 1.8 unterstützt, da ich das hier benutze. Sie müssen Ihre Implementierung auf den Support-Level überprüfen.
Es wurde angefordert, dass JPA 2.2 die Java.time-Typen unterstützt. Weitere Informationen finden Sie in dieser Ausgabe https://Java.net/jira/browse/JPA_SPEC-63
Für Hibernate 5.X einfach hinzufügen
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-Java8</artifactId>
<version>${hibernate.version}</version>
</dependency>
und
@NotNull
@Column(name = "date_time", nullable = false)
protected LocalDateTime dateTime;
funktioniert ohne zusätzlichen Aufwand . Siehe https://hibernate.atlassian.net/browse/HHH-8844
AKTUALISIEREN:
Schauen Sie sich bitte Jeff Morins Kommentar an: Seit Hibernate 5.2.x reicht es aus
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>5.2.1.Final</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-...</artifactId>
<version>4.3.1.RELEASE</version>
</dependency>
Siehe https://github.com/hibernate/hibernate-orm/wiki/Migration-Guide---5.2 und Integrieren Sie Hibernate 5.2 mit Spring Framework 4.x
JPA 2.2 unterstützt jetzt LocalDate
, LocalTime
, LocalDateTime
, OffsetTime
und OffsetDateTime
.
<dependency>
<groupId>javax.persistence</groupId>
<artifactId>javax.persistence-api</artifactId>
<version>2.2</version>
</dependency>
Für die Implementierung von JPA 2.2 können Hibernate 5.2 oder EclipseLink 2.7 verwendet werden.
Der Ruhezustand 5 unterstützt mehr Java-Typen als JPA 2.2 wie Duration
, Instant
und ZonedDateTime
.
Mehr Info:
Ich verwende Java 8, EclipseLink (JPA 2.1), PostgreSQL 9.3 und PostgreSQL Driver -Postgresql-9.2-1002.jdbc4.jar in meinem Projekt, und ich kann LocalDateTime-Variablen aus der neuen API ohne Probleme verwenden, aber den Datentyp der Spalte Da es sich in der Datenbank um Bytea handelt, können Sie es nur von einer Java-Anwendung lesen, soweit ich weiß. Sie können AttributeConverter verwenden, um die neuen Klassen in Java.sql.Date .__ zu konvertieren. Ich finde diesen Code von Java.net .
@Converter(autoApply = true)
public class LocalDatePersistenceConverter implements
AttributeConverter {
@Override
public Java.sql.Date convertToDatabaseColumn(LocalDate entityValue) {
return Java.sql.Date.valueOf(entityValue);
}
@Override
public LocalDate convertToEntityAttribute(Java.sql.Date databaseValue) {
return databaseValue.toLocalDate();
}
org.jadira.usertype kann verwendet werden, um die JSR 310-API für Datum und Uhrzeit zu persistieren.
Schauen Sie sich dieses Beispielprojekt an.
Aus Beispielprojekt,
@MappedSuperclass
public class AbstractEntity {
@Id @GeneratedValue Long id;
@CreatedDate//
@Type(type = "org.jadira.usertype.dateandtime.threeten.PersistentZonedDateTime")//
ZonedDateTime createdDate;
@LastModifiedDate//
@Type(type = "org.jadira.usertype.dateandtime.threeten.PersistentZonedDateTime")//
ZonedDateTime modifiedDate;
}
Ich weiß, dass dies eine alte Frage ist, aber ich dachte an eine alternative Lösung, die hilfreich sein könnte.
Anstatt zu versuchen, die neuen Java.time. * - Klassen einem vorhandenen Datenbanktyp zuzuordnen, können Sie @Transient nutzen:
@Entity
public class Person {
private Long id;
private Timestamp createdTimestamp;
@Id
@GeneratedValue
public Long getId() { return id; }
private Timestamp getCreatedTimestamp() {
return createdTime;
}
private void setCreatedTimestamp(final Timestamp ts) {
this.createdTimestamp = ts;
}
@Transient
public LocalDateTime getCreatedDateTime() {
return createdTime.getLocalDateTime();
}
public void setCreatedDateTime(final LocalDateTime dt) {
this.createdTime = Timestamp.valueOf(dt);
}
}
Sie arbeiten mit den öffentlichen Getter/Setter-Methoden, die die neuen Java 8-Datums-/Zeitklassen verwenden, aber hinter den Kulissen arbeiten die Getter/Setter mit den älteren Datums-/Zeitklassen. Wenn Sie die Entität beibehalten, wird die alte Datums-/Uhrzeit-Eigenschaft beibehalten, nicht jedoch die neue Java 8-Eigenschaft, da sie mit @Transient kommentiert wird.
Für den TypTIMESTAMPkönnen Sie diesen Konverter verwenden:
@Converter(autoApply = true)
public class LocalDateTimeAttributeConverter implements AttributeConverter<LocalDateTime, Timestamp> {
@Override
public Timestamp convertToDatabaseColumn(LocalDateTime datetime) {
return datetime == null ? null : Timestamp.valueOf(datetime);
}
@Override
public LocalDateTime convertToEntityAttribute(Timestamp timestamp) {
return timestamp == null ? null : timestamp.toLocalDateTime();
}
}
Für den TypDATEkönnen Sie diesen Konverter verwenden:
@Converter(autoApply = true)
public class LocalDateAttributeConverter implements AttributeConverter<LocalDate, Date> {
@Override
public Date convertToDatabaseColumn(LocalDate date) {
return date == null ? null : Date.valueOf(date);
}
@Override
public LocalDate convertToEntityAttribute(Date date) {
return date == null ? null : date.toLocalDate();
}
}
Für den TypTIMEkönnen Sie diesen Konverter verwenden:
@Converter(autoApply = true)
public class LocalTimeAttributeConverter implements AttributeConverter<LocalTime, Time> {
@Override
public Time convertToDatabaseColumn(LocalTime time) {
return time == null ? null : Time.valueOf(time);
}
@Override
public LocalTime convertToEntityAttribute(Time time) {
return time == null ? null : time.toLocalTime();
}
}
Es gibt viele Vorgehensweisen, die auch von Ihrer Rahmenarbeit abhängig sind: Wenn Ihre Rahmenarbeit auf dem Feldumwandler einen solchen Frühling hat, tun Sie Folgendes:
@DateTimeFormat(pattern = "dd.MM.yyyy - HH:mm")
private Long createdDate;
hier verwende ich das ältere Epoch-Format https://www.epochconverter.com/ Epoch ist sehr flexibel und akzeptiert das Format
2- Die andere Möglichkeit ist die Verwendung von jpa @PostLoad @PreUpdate @PrePersist
@PostLoad
public void convert() {
this.jva8Date= LocalDate.now().plusDays(1);
}
oder verwenden Sie temporär ein solches
@Transient
public LocalDateTime getCreatedDateTime() {
return createdTime.getLocalDateTime();
}