适用于AuditingEntityListener的Spring JPA Hibernate CET时区

时间:2019-03-19 21:48:58

标签: java spring spring-boot jdbc spring-data-jpa

我没有为我的JPA应用程序设置CET时区,该时区使用AuditingEntityListener来增加创建/最后修改的日期。

我已经尝试过的事情:

在我的application.properties中(两种组合):

<script>
import store from '@state/store'
import { calendarComputed } from '@state/helpers'

export default {
  data() {
    return {
      calendar: null,
    }
  },
  computed: {
    ...calendarComputed,
  },
  created() {
    // Are calendars already persisted?
    if (!this.calendars.length) {
      store.dispatch('calendar/getCalendars').then((res) => {
        this.calendar = res.find((calendar) => { if (calendar.id == this.$route.params.id) return calendar })
      })
    } else {
      this.calendar = this.calendars.find((calendar) => { if (calendar.id == this.$route.params.id) return calendar })
    }
  },
}
</script>

为我的JDBC连接(两种组合)添加了时区

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

添加了后构建(应用程序级别)

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"));
}

无论如何都没有成功,我错过了什么吗?

按如下所示使用@createdDate:

编辑

SET time_zone='+01:00';

4 个答案:

答案 0 :(得分:0)

尝试“ 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);

答案 1 :(得分:0)

将配置添加到application.properties适用于Hibernate 5.2.3+。目前尚不清楚您使用的是哪个版本。

处理此问题的另一种方法是在IDE的运行配置中设置JVM参数-Duser.timezone=CET,或者从命令行/脚本/泊坞窗等运行应用程序。

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

检查设置JVM时区是否影响您的用例。

答案 2 :(得分:0)

您可以这样使用:

@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服务器的时区将无济于事。

答案 3 :(得分:0)

我遇到了同样的问题,并通过配置一个使用UTC而不是系统时区的自定义DateTimeProvider来解决了该问题,请参见下面的代码。

上面提到的手动设置值的解决方案对我来说不合适,因为它混合了Spring JPA扩展和EntityListener支持,为什么还要使用Spring的JPA Auditing?

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

我希望这会有所帮助:)