Spring JPA Hibernate CET часовой пояс для AuditingEntityListener - PullRequest
7 голосов
/ 20 марта 2019

Мне не удается установить часовой пояс CET для моего приложения JPA, которое использует AuditingEntityListener для увеличения дат создания / последнего изменения.

То, что я уже пробовал:

В моем приложении. Свойства (обе комбинации):

spring.jpa.properties.hibernate.jdbc.time_zone=UTC+1
spring.jpa.properties.hibernate.jdbc.time_zone=CET

Добавлен часовой пояс для моего соединения JDBC (обе комбинации)

spring.datasource.url=jdbc:mysql://host:3306/db?useUnicode=true&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=UTC+1
spring.datasource.url=jdbc:mysql://host:3306/db?useUnicode=true&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=CET

Добавлена ​​постконструктура (уровень приложения)

@PostConstruct
void started() {
    TimeZone.setDefault(TimeZone.getTimeZone("UTC+1"));
}

А также попытался установить часовой пояс на уровне базы данных, используя:

SET time_zone='+01:00';

Безуспешно, я что-то упустил?

Использование @createdDate следующим образом:

EDIT

@Data
@Builder
@Entity
@EntityListeners(AuditingEntityListener.class)
@NoArgsConstructor
@AllArgsConstructor
public class OrderHistoryRecord {
    @Id
    @GeneratedValue
    @JsonIgnore
    private Long id;

    @NotNull
    @ManyToOne(fetch = FetchType.LAZY, targetEntity = Order.class)
    @JoinColumn(name = "order_id", updatable = false)
    @JsonIgnore
    private Order order;

    @CreatedDate
    private Date date;

    @Enumerated(EnumType.STRING)
    private PaymentStatus paymentStatus;

    @Enumerated(EnumType.STRING)
    private ShipmentStatus shipmentStatus;

    @Enumerated(EnumType.STRING)
    private OrderHistoryRecordType type;
}

Ответы [ 4 ]

0 голосов
/ 21 июля 2019

У меня была та же проблема, и я решил ее, настроив пользовательский DateTimeProvider, который использует UTC вместо системного часового пояса, см. Код ниже.

Упомянутое решение для установки значений вручную мне кажется неправильным, потому что оноСмешивает расширение Spring JPA и поддержку EntityListener. Зачем вообще использовать JPA Auditing из Spring?

Решение для Spring Boot 1

@Configuration
@EnableJpaAuditing(dateTimeProviderRef = "utcDateTimeProvider")
public class JpaConfig {
    @Bean
    public DateTimeProvider utcDateTimeProvider() {
        return () -> new GregorianCalendar(TimeZone.getTimeZone("UTC"));
    }
}

Почему Gregoriancalendar? Spring преобразует объект типа GregorianCalendar в LocalDateTime с помощью преобразователей Jsr310Converters.

Решение для Spring Boot 2

@Configuration
@EnableJpaAuditing(dateTimeProviderRef = "utcDateTimeProvider")
public class JpaConfig {
    @Bean
    public DateTimeProvider utcDateTimeProvider() {
        return () -> Optional.of(LocalDateTime.now(ZoneOffset.UTC));
    }
}

Надеюсь, это поможет:)

0 голосов
/ 28 марта 2019

Добавление конфигурации к application.properties работает для Hibernate 5.2.3 + .Непонятно, какую версию вы используете.

Другой способ справиться с этим - установить параметр JVM -Duser.timezone=CET в конфигурации запуска вашей IDE или если вы запускаете приложение из командной строки / сценария / докера и т. Д.:

java -Duser.timezone=CET -jar your-jdbc-app.jar

Проверьте, влияет ли настройка часового пояса JVM на ваши сценарии использования.

0 голосов
/ 01 апреля 2019

Вы можете использовать так:

@CreatedDate
@Column(name = "created_date", nullable = false, updatable = false)
private LocalDateTime createdDate;

@LastModifiedDate
@Column(name = "last_modified_date")
private LocalDateTime lastModifiedDate;

@PrePersist
public void onCreate() {
    this.createdDate = LocalDateTime.now(ZoneId.of("UTC"));
    this.lastModifiedDate = LocalDateTime.now(ZoneId.of("UTC"));
}

@PreUpdate
public void onUpdate() {
    this.lastModifiedDate = LocalDateTime.now(ZoneId.of("UTC"));
}

Spring внутренне назвал эти аннотации (@PrePersist и @PreUpdate перед вставкой или обновлением записей соответственно). Вы можете переопределить эти аннотации способом, чтобы создать собственную реализацию. В противном случае время на вашем сервере базы данных возрастет. Изменение часового пояса Java-сервера вам не поможет.

0 голосов
/ 27 марта 2019

Попробуйте "ECT"?

    Map<String, String> map = new HashMap<>(64);
    map.put("ACT", "Australia/Darwin");
    map.put("AET", "Australia/Sydney");
    map.put("AGT", "America/Argentina/Buenos_Aires");
    map.put("ART", "Africa/Cairo");
    map.put("AST", "America/Anchorage");
    map.put("BET", "America/Sao_Paulo");
    map.put("BST", "Asia/Dhaka");
    map.put("CAT", "Africa/Harare");
    map.put("CNT", "America/St_Johns");
    map.put("CST", "America/Chicago");
    map.put("CTT", "Asia/Shanghai");
    map.put("EAT", "Africa/Addis_Ababa");
    map.put("ECT", "Europe/Paris");
    map.put("IET", "America/Indiana/Indianapolis");
    map.put("IST", "Asia/Kolkata");
    map.put("JST", "Asia/Tokyo");
    map.put("MIT", "Pacific/Apia");
    map.put("NET", "Asia/Yerevan");
    map.put("NST", "Pacific/Auckland");
    map.put("PLT", "Asia/Karachi");
    map.put("PNT", "America/Phoenix");
    map.put("PRT", "America/Puerto_Rico");
    map.put("PST", "America/Los_Angeles");
    map.put("SST", "Pacific/Guadalcanal");
    map.put("VST", "Asia/Ho_Chi_Minh");
    map.put("EST", "-05:00");
    map.put("MST", "-07:00");
    map.put("HST", "-10:00");
    SHORT_IDS = Collections.unmodifiableMap(map);
...