Spring Boot 3搭配PostgreSQL时Instant映射timestamp失败问题
Spring Boot 3(Hibernate 6.1)+ PostgreSQL 下Instant映射timestamp without time zone的问题
在Spring Boot 3(搭配Hibernate 6.1)与PostgreSQL结合使用时,将Instant值映射到SQL timestamp without time zone类型会出现问题——执行测试用例时,读取的值与写入的值相差本地时区偏移量。但切换到H2测试数据库,或者回退到Spring Boot 2.7.6(Hibernate 5.6)时,测试用例可正常通过。
JPA实体
@Entity public class MyEntity { @Id UUID id = UUID.randomUUID(); //@JdbcType(TimestampJdbcType.class) //临时解决方法 //(替代方案:在自定义Hibernate方言中全局声明) //为何仅Spring Boot3+PostgreSQL需要此配置? @Column(columnDefinition = "timestamp") Instant createdTimestamp = Instant.now(); }
Spring Data仓库
public interface MyEntityRepository extends CrudRepository<MyEntity, UUID> { }
JUnit集成测试
@DataJpaTest @AutoConfigureTestDatabase(replace = Replace.NONE) //注释此行以使用H2数据库 class MyEntityRepositoryITest { @Autowired MyEntityRepository myEntityRepository; @Test @Transactional(propagation = NOT_SUPPORTED) //不使用事务 void readInstantSameAsPersisted() { var entity = new MyEntity(); myEntityRepository.save(entity); var read = myEntityRepository.findById(entity.id).orElseThrow(); assertEquals(entity.createdTimestamp.getEpochSecond(), read.createdTimestamp.getEpochSecond()); } }
Maven pom.xml依赖
<dependency> <groupId>org.postgresql</groupId> <artifactId>postgresql</artifactId> <scope>runtime</scope> </dependency> <dependency> <groupId>com.h2database</groupId> <artifactId>h2</artifactId> <scope>test</scope> </dependency>
Spring application.properties配置
spring.jpa.hibernate.ddl-auto=create spring.datasource.url=jdbc:postgresql://localhost:5432/dbname spring.datasource.username=username spring.datasource.password=password
注意事项
- 设置
spring.jpa.properties.hibernate.jdbc.time_zone无效果。 - 不考虑切换为
LocalDateTime,因为需要createdTimestamp表示明确的时间点。 - 不考虑切换为带时区信息的SQL类型,不希望数据库中存在时区各异的值。
spring.datasource.hikari.connection-init-sql=SET TIME ZONE 'UTC'可作为临时解决方法,但不解为何需要此配置——读取基于1970-01-01以来秒数的值应与写入值一致,与后台时区无关。- pgJDBC不支持
Instant,但Hibernate支持。 - 相关Stack Overflow回答可能有关联,但为何旧版Hibernate可正常工作?
更新
某Stack Overflow回答指出,timestamp with time zone并不像名称所示携带额外时区信息,仅存储UTC时间线上的一个点,可在不同时区展示,似乎更适配此场景。
内容的提问来源于stack exchange,提问作者Knight Industries
相关产品推荐
相关产品推荐

