it-swarm.com.ru

Поддержка JPA для нового API даты и времени в Java 8

Я использую Java 8 для моего нового проекта.

Я пытаюсь использовать новые API даты и времени в Java 8, однако я не знаю, полностью ли JPA 2.1 поддерживает этот новый API даты и времени или нет.

Пожалуйста, поделитесь своим опытом/мнением в поддержке JPA для нового API даты и времени в Java 8.

Могу ли я безопасно использовать новые API даты и времени в Java 8 с JPA 2.1?

Обновление:

Я использую Hibernate (4.3.5.Final) в качестве реализации JPA.

53
TheKojuEffect

JPA 2.1 - это спецификация, которая вышла до Java 1.8, поэтому не требует ее поддержки. Очевидно, что некоторые реализации могут поддерживать некоторые функции Java 1.8. Некоторые имеют проблемы с байт-кодом Java 1.8 (например, EclipseLink). Я знаю, что DataNucleus поддерживает Java.time и Java 1.8, так как это то, что я использую. Вы должны проверить свою реализацию на предмет ее уровня поддержки.

Было запрошено, чтобы JPA 2.2 поддерживал типы Java.time, см. Эту проблему https://Java.net/jira/browse/JPA_SPEC-63

19
Neil Stockton

Для Hibernate 5.X просто добавьте

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

а также 

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

будет работать без каких-либо дополнительных усилий . См. https://hibernate.atlassian.net/browse/HHH-8844

Обновление:

Пожалуйста, взгляните на комментарий Джеффа Морина: начиная с Hibernate 5.2.x этого достаточно

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

См. https://github.com/hibernate/hibernate-orm/wiki/Migration-Guide---5.2 and Интегрируйте Hibernate 5.2 с Spring Framework 4.x

70
GKislin

JPA 2.2 поддерживает Java.time

JPA 2.2 теперь поддерживает LocalDate, LocalTime, LocalDateTime, OffsetTime и OffsetDateTime.

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

Для реализации JPA 2.2 можно использовать Hibernate 5.2 или EclipseLink 2.7.

Hibernate 5 поддерживает больше типов Java, чем JPA 2.2, таких как Duration, Instant и ZonedDateTime.

Больше информации: 

10
TheKojuEffect

Я использую Java 8, EclipseLink (JPA 2.1), PostgreSQL 9.3 и драйвер PostgreSQL -Postgresql-9.2-1002.jdbc4.jar в своем проекте, и я могу использовать переменные LocalDateTime из нового API без проблем, но с типом данных столбца Насколько я знаю, в базе данных есть bytea, так что вы можете читать его только из Java-приложения. Вы можете использовать AttributeConverter для преобразования новых классов в Java.sql.Date Я нахожу этот код из 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
Ismael_Diaz

org.jadira.usertype может использоваться для сохранения API даты и времени JSR 310.

Проверьте это пример проекта

Из примера проекта,

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

Я знаю, что это старый вопрос, но я подумал об альтернативном решении, которое может быть полезным.

Вместо того чтобы пытаться сопоставить новые классы Java.time. * С существующими типами базы данных, вы можете использовать @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);
    }
}

Вы работаете с общедоступными методами получения/установки, которые используют новые классы даты/времени Java 8, но за кулисами методы получения/установки работают с унаследованными классами даты/времени. Когда вы сохраняете сущность, устаревшее свойство даты/времени будет сохранено, но не новое свойство Java 8, так как оно аннотировано @Transient.

3
Jin Kim

Для типаTIMESTAMPвы можете использовать этот конвертер:

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

}

Для типаДАТАвы можете использовать этот конвертер:

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

}

Для типаВРЕМЯвы можете использовать этот конвертер:

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

Существует множество подходов к выполнению, также это зависит от вашей каркасной работы: Если ваша каркасная работа имеет на поле конвертер такую ​​пружину, сделайте такую: 1-

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

здесь я использую устаревший формат Epoch https://www.epochconverter.com/ Epoch очень гибкий и принятый формат

2- Другой способ - использовать jpa @PostLoad @PreUpdate @PrePersist

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

или использовать временный один такой 

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