Prise en charge de JPA pour L'API Date et heure de Java 8

J'utilise Java 8 pour mon nouveau projet.

j'essaye d'utiliser une nouvelle api date et heure en java 8 mais je ne sais pas si JPA 2.1 supporte entièrement cette nouvelle API Date et heure ou pas.

s'il vous plaît partager votre expérience/opinion dans les supports de JPA pour la nouvelle API date et heure en Java 8.

puis-je utiliser la nouvelle api date et heure de Java 8 en toute sécurité avec JPA 2.1?

Mise à jour:

J'utilise hibernation (4.3.5.Final) en tant que mise en œuvre de L'app.

52
demandé sur JodaStephen 2014-05-18 07:50:38

8 réponses

JPA 2.1 est une spécification qui est sorti avant Java 1.8, donc ne nécessite aucun soutien pour elle. De toute évidence, certaines implémentations peuvent prendre en charge certaines fonctionnalités Java 1.8. Certains ont des problèmes avec Java 1.8 bytecode(E. G EclipseLink). Je sais que DataNucleus supporte java.temps et Java 1.8 puisque c'est celui que j'utilise. Vous devez vérifier votre implémentation pour connaître son niveau de support.

il a été demandé que JPA 2.2 supporte java.les types d'heures, voir à ce sujet https://java.net/jira/browse/JPA_SPEC-63

18
répondu Neil Stockton 2016-07-12 08:39:18

Pour Hibernation 5.X il suffit d'ajouter

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

et

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

fonctionnera sans aucun effort supplémentaire. Voir https://hibernate.atlassian.net/browse/HHH-8844

mise à jour:

, jetez un oeil à Jeff Morin commentaire: comme Hibernate 5.2.x il suffit

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

voir https://github.com/hibernate/hibernate-orm/wiki/Migration-Guide---5.2 et Intégrer Hibernate 5.2 avec Spring framework 4.x

70
répondu GKislin 2017-05-23 12:26:32

JPA 2.2 supporte java.temps

JPA 2.2 prend désormais en charge LocalDate , LocalTime , LocalDateTime , OffsetTime et OffsetDateTime .

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

pour la mise en œuvre de la JPA 2.2, hibernation 5.2 ou EclipseLink 2.7 peut être utilisé.

Hibernate 5 supporte plus de types java que JPA 2.2 comme Duration , Instant et ZonedDateTime .

Plus D'Informations:

10
répondu TheKojuEffect 2018-08-22 19:44:31

J'utilise Java 8, EclipseLink(JPA 2.1),PostgreSQL 9.3 et PostgreSQL Driver-Postgresql-9.2-1002.jdbc4.jar dans mon projet et je peux utiliser les variables LocalDateTime de la nouvelle API sans problème mais le type de données de la colonne est bytea dans la base de données, donc vous ne pouvez le lire à partir d'une application Java autant que je sache. Vous pouvez utiliser AttributeConverter pour convertir les nouvelles classes en java.SQL.Date Je trouve ce code 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();
}
9
répondu Ismael_Diaz 2014-07-03 22:24:50

org.jadira.usertype peut être utilisé pour persister JSR 310 date and Time API.

Regardez ce exemple de projet .

À Partir De L'Exemple De Projet,

@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;
}
8
répondu TheKojuEffect 2014-10-10 04:11:40

je sais que c'est une vieille question, mais j'ai pensé à une solution alternative qui pourrait être utile.

au lieu d'essayer de cartographier le nouveau java.temps.* classes à un type de base de données existant, vous pouvez tirer profit de @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);
    }
}

vous travaillez avec les méthodes getter/setter publiques qui utilisent les nouvelles classes date/time de Java 8, mais dans les coulisses le getter/setter fonctionne avec les classes Date/time héritées. Lorsque vous persistez l'entité, la propriété legacy date/time sera persistée mais pas la nouvelle propriété Java 8 puisqu'elle est annotée avec @Transient.

3
répondu Jin Kim 2014-12-14 19:26:01

pour le type TIMESTAMP vous pouvez utiliser ce convertisseur:

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

}

pour le type DATE vous pouvez utiliser ce convertisseur:

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

}

pour le type TIME vous pouvez utiliser ce convertisseur:

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

}
1
répondu Paco 2017-10-10 16:59:30

Il ya beaucoup d'approche à faire , aussi il dépend de votre cadre : Si votre travail de cadre a sur le convertisseur de champ tel ressort font tel: 1 -

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

j'utilise le format legacy epoch https://www.epochconverter.com / l'époque est très souple et de format accepté

2 - l'autre façon est D'utiliser jpa @PostLoad @PreUpdate @PrePersist

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

ou utiliser un tel temp

@Transient
public LocalDateTime getCreatedDateTime() {
    return createdTime.getLocalDateTime();
}
0
répondu Ali.Mojtehedy 2017-08-27 10:15:48