JPA Модельный класс для поля TIMESTAMP БЕЗ ВРЕМЕННОЙ ЗОНЫ ПО УМОЛЧАНИЮ CURRENT_TIMESTAMP в Postgres? - PullRequest
0 голосов
/ 08 июля 2019

Ниже таблица в Postgres и использование Java 8 и Postgres-11 с Spring Boot 2.1.6.RELEASE .Я уже прошел по ссылке: Как сопоставить столбец отметки времени с типом JPA? и Hibernate создает столбец без имени при использовании "CURRENT_TIMESTAMP по умолчанию при обновлении CURRENT_TIMESTAMP" , но я действительно хотел использоватьJava 8 Date API, а не Java 7.

CREATE TABLE note(
    note_id serial PRIMARY KEY,
    message varchar(255) NOT NULL,
    created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP
);

Я создал класс модели, как показано ниже, но не соответствует тому, что мне нужно.Любая помощь?

@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
@EqualsAndHashCode(callSuper = true)
@Entity
public class Note extends AuditEnabledEntity{
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "note_id")
    private int noteId;

    @Column(name = "message")
    private String message;

    @Column(name = "created_at")
    private LocalDateTime createdAt;
}

1 Ответ

1 голос
/ 08 июля 2019

Table of all date-time types in Java (both modern & legacy) as well as SQL standard.

Неправильный тип

LocalDateTime неправильный тип здесь. Этот класс не может представлять момент, как объяснено в его Javadoc.

Этот класс намеренно не имеет понятия о часовом поясе или смещении от UTC. Таким образом, он представляет дату и время суток, такие как «полдень 23 января 2019 года», но не знаю, будет ли это полдень в Токио, Париже или Монреале, например, три совершенно разных момента, которые несколько часов друг от друга. Так что этот тип подходит для стандартного типа SQL TIMESTAMP WITHOUT TIME ZONE - без , а не с .

Подробнее об этом см .: В чем разница между Instant и LocalDateTime?

Правильный тип

Для стандартного типа SQL TIMESTAMP WITH TIME ZONE вы должны использовать типы Java Instant, OffsetDateTime или ZonedDateTime. Из этих трех JDBC 4.2 требует поддержки только для второго, OffsetDateTime.

индексирование.

OffsetDateTime odt = myResultSet.getObject( … , OffsetDateTime.class ) ;

Значение, полученное из Postgres, всегда будет в UTC. Стандарт SQL не определяет это поведение, поэтому базы данных различаются. В Postgres любое значение, отправляемое в поле типа TIMESTAMP WITH TIME ZONE, настраивается в UTC. Полученные значения в UTC.

Запоминание.

myPreparedStatement.setObject( … , odt ) ;

Настройте UTC (смещение нуля) на время настенных часов, используемое людьми определенного региона (часового пояса).

ZoneId z = ZoneId.of( "Asia/Tokyo" ;
ZonedDateTime zdt = odt.atZoneSameInstant( z ) ;

JPA

Я не использую JPA, предпочитаю быть проще.

Но согласно этому ответу , JPA 2.2 поддерживает типы java.time .

Hibernate также поддерживает java.time .

...