localdatetime java jpa java-8 jpa-2.1 java-time

localdatetime - Compatibilidad con JPA para la nueva API de fecha y hora de Java 8



hibernate localdatetime (8)

Estoy usando Java 8 para mi nuevo proyecto.

Estoy intentando usar una nueva API de fecha y hora en java 8, pero no sé si JPA 2.1 totalmente compatible con esta nueva API de fecha y hora o no.

Comparta su experiencia / opinión en los soportes de JPA para la nueva API de fecha y hora en Java 8.

¿Puedo usar una nueva API de fecha y hora en Java 8 de forma segura con JPA 2.1?

ACTUALIZAR:

Estoy usando Hibernate (4.3.5.Final) como implementación de JPA.


JPA 2.2 es compatible con java.time

JPA 2.2 ahora es compatible con LocalDate , LocalTime , LocalDateTime , OffsetTime y OffsetDateTime .

<dependency> <groupId>javax.persistence</groupId> <artifactId>javax.persistence-api</artifactId> <version>2.2</version> </dependency>

Para la implementación de JPA 2.2, se puede usar Hibernate 5.2 o EclipseLink 2.7 .

Hibernate 5 admite más tipos de Java que JPA 2.2, como Duration , Instant y ZonedDateTime .

Más información:


Estoy usando Java 8, EclipseLink (JPA 2.1), PostgreSQL 9.3 y PostgreSQL Driver -Postgresql-9.2-1002.jdbc4.jar en mi proyecto y puedo usar las variables LocalDateTime desde la nueva API sin problema, pero el tipo de datos de la columna es bytea en la base de datos, por lo que solo se puede leer desde una aplicación Java hasta donde yo sé. Puede usar AttributeConverter para convertir las nuevas clases a java.sql.Date. Encontré este código de 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(); }


Hay muchos enfoques para hacer, también depende de su trabajo de marco: si su marco de trabajo tiene en campo convertidor de primavera hacer tal: 1-

@DateTimeFormat(pattern = "dd.MM.yyyy - HH:mm") private Long createdDate;

Aquí estoy usando el formato de época legado https://www.epochconverter.com/ es un formato muy flexible y aceptado

2- Las otras formas es usar jpa @PostLoad @PreUpdate @PrePersist

@PostLoad public void convert() { this.jva8Date= LocalDate.now().plusDays(1); }

o use la temperatura uno tal

@Transient public LocalDateTime getCreatedDateTime() { return createdTime.getLocalDateTime(); }


JPA 2.1 es una especificación que apareció antes de Java 1.8, por lo que no exige ningún soporte para ella. Obviamente, algunas implementaciones pueden admitir algunas características de Java 1.8. Algunos tienen problemas con Java 1.8 bytecode (por ejemplo, EclipseLink). Sé que DataNucleus admite java.time y Java 1.8 ya que es el que uso. Debería verificar su implementación para saber cuál es su nivel de soporte.

Se ha solicitado que JPA 2.2 admita los tipos java.time, consulte este tema https://java.net/jira/browse/JPA_SPEC-63


Para Hibernate 5.X simplemente agregue

<dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-java8</artifactId> <version>${hibernate.version}</version> </dependency>

y

@NotNull @Column(name = "date_time", nullable = false) protected LocalDateTime dateTime;

funcionará sin ningún esfuerzo adicional. Ver hibernate.atlassian.net/browse/HHH-8844

ACTUALIZAR:

Eche un vistazo al comentario de Jeff Morin: desde Hibernate 5.2.x es suficiente

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

Consulte https://github.com/hibernate/hibernate-orm/wiki/Migration-Guide---5.2 e Integre Hibernate 5.2 con Spring framework 4.x


Para el tipo TIMESTAMP puede usar este convertidor:

@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(); } }

Para el tipo DATE , puede usar este convertidor:

@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(); } }

Para el tipo TIME , puede usar este convertidor:

@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(); } }


Sé que esta es una vieja pregunta, pero pensé en una solución alternativa que podría ser útil.

En lugar de intentar asignar las nuevas clases java.time. * A un tipo de base de datos existente, puede aprovechar @Transient:

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

Trabaja con los métodos getter / setter públicos que usan las nuevas clases de fecha / hora de Java 8, pero detrás de escena, los getter / setters trabajan con las clases heredadas de fecha / hora. Cuando persiste la entidad, se conservará la propiedad de fecha / hora heredada, pero no la nueva propiedad de Java 8, ya que está anotada con @Transient.


org.jadira.usertype se puede utilizar para persistir JSR 310 Fecha y hora API.

Mira este github.com/spring-projects/spring-data-examples/blob/master/… .

De Proyecto de ejemplo,

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