Поддержка JPA для Java 8 новый API даты и времени
Я использую Java 8 для моего нового проекта.
Я пытаюсь использовать новый api даты и времени в java 8, однако я не знаю, если JPA 2.1
полностью поддерживает этот новый API даты и времени или нет.
пожалуйста, поделитесь своим опытом / мнением в поддержке JPA для нового API даты и времени в Java 8.
могу ли я использовать новый api даты и времени в Java 8 безопасно с JPA 2.1?
обновление:
Я использую Hibernate (4.3.5.Финал) как Реализация JPA.
8 ответов:
JPA 2.1-это спецификация, которая вышла до Java 1.8, поэтому не требует никакой поддержки для нее. Очевидно, что некоторые реализации могут поддерживать некоторые функции Java 1.8. У некоторых есть проблемы с байт-кодом Java 1.8 (например, EclipseLink). Я знаю, что DataNucleus поддерживает java.время и Java 1.8, так как это тот, который я использую. Вам нужно будет проверить свою реализацию на то, каков ее уровень поддержки.
было запрошено, что JPA 2.2 поддерживает java.времени, ознакомиться с этим вопросом https://java.net/jira/browse/JPA_SPEC-63
Для Гибернации 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 и интеграция Hibernate 5.2 с весной рамки 4.x
JPA 2.2 поддерживает java.время
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
.Подробнее:
Я использую Java 8, EclipseLink (JPA 2.1),PostgreSQL 9.3 и драйвер PostgreSQL-Postgresql-9.2-1002.jdbc4.jar в моем проекте, и я могу использовать переменные LocalDateTime из нового API без проблем, но тип данных столбца-bytea в базе данных, поэтому вы можете читать его только из приложения Java, насколько я знаю. Вы можете использовать AttributeConverter для преобразования новых классов в java.язык SQL.Дата Я нахожу этот код от 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(); }
орг.jadira.usertype может использоваться для сохранения JSR 310 дата и время API.
зацените пример проекта.
Из Примера Проекта,
@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; }
Я знаю, что это старый вопрос, но я подумал об альтернативном решении, которое может быть полезно.
вместо того, чтобы пытаться сопоставить новую java.время.* классы для существующих типов баз данных, вы можете использовать @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); } }
вы работаете с общедоступными методами getter / setter, которые используют новые классы даты/времени Java 8, но за кулисами getter/setters работают с устаревшими классами даты/времени. При сохранении сущности устаревшее свойство даты / времени будет сохранено, но не новое свойство Java 8, так как оно аннотировано с помощью @Transient.
тип метка вы можете использовать этот конвертер:
@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-
@DateTimeFormat(pattern = "dd.MM.yyyy - HH:mm") private Long createdDate;
здесь я использую формат legacy epoch https://www.epochconverter.com/ эпоха - это очень гибкий и приемлемый формат
2-другие способы-использовать jpa @PostLoad @PreUpdate @PrePersist
@PostLoad public void convert() { this.jva8Date= LocalDate.now().plusDays(1); }
или используйте temp один такой
@Transient public LocalDateTime getCreatedDateTime() { return createdTime.getLocalDateTime(); }