You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring Boot+MariaDB中JSON字段ZonedDateTime时区转换异常问题

Spring Boot + MariaDB 存储JSON字段时ZonedDateTime时区丢失问题

项目环境与代码实现

我正在开发一个基于Spring Boot和MariaDB的项目,需要将Student实体中的Exam属性以JSON格式存储到数据库中。相关代码和配置如下:

数据库表结构

CREATE TABLE IF NOT EXISTS student (
    id bigint not null,
    exam json,
    first_name varchar(255),
    last_name varchar(255),
    primary key (id)
) engine=InnoDB;

Student实体类

使用JsonStringType将Exam属性映射为JSON字段:

@Data
@NoArgsConstructor
@AllArgsConstructor
@Entity
@TypeDefs({
    @TypeDef(name = "json", typeClass = JsonStringType.class)
})
public class Student implements Serializable {
    // 其他属性省略...

    @Column(columnDefinition = "LONGTEXT")
    @Type(type = "json")
    private Exam exam;
}

Exam普通类

Exam并非JPA实体,只是包含ZonedDateTime类型属性的普通类:

@Data
@NoArgsConstructor
@AllArgsConstructor
public class Exam implements Serializable {
    private ZonedDateTime startTime;
    private String code;
}

Repository接口

@Repository
public interface StudentRepository extends JpaRepository<Student, Long> {
}

单元测试代码

测试数据生成方法

public Student createStudentEntity() {
    // 生成带当前时区(Europe/Paris)时间的Exam对象
    Exam exam = new Exam(ZonedDateTime.now(), "math01");

    Student student = new Student();
    student.setExam(exam);
    // 其他属性赋值省略...
    return student;
}

测试用例

@ActiveProfiles("test")
@SpringBootTest
class StudentTest {

    @Autowired
    StudentRepository studentRepo;
    
    @Test
    void test_save_student() {
        Student student = MyTestHelper.createStudentEntity();
        studentRepo.save(student);

        // 断言失败,时区不匹配
        Assertions.assertEquals(student, studentRepo.findById(student.getId()).get());
    }
}

问题现象

测试执行后断言失败,错误信息如下:

AssertionFailedError: expected: <Student(id=123,exam=Exam(startTime=2023-04-24T20:58:57.624489+03:00[Europe/Paris],...> but was: <Student(id=123,exam=Exam(startTime=2023-04-24T20:58:57.624489+03:00[UTC],...>

核心问题:

  • 存入数据库前,Exam.startTime的时区为Europe/Paris
  • 从数据库取出后,startTime的时区变为UTC

已尝试的无效方案

给Exam.startTime添加Jackson的@JsonFormat注解指定时区:

@Data
@NoArgsConstructor
@AllArgsConstructor
public class Exam implements Serializable {
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss.SSSZ", timezone = "Europe/Paris")
    private ZonedDateTime startTime;
    private String code;
}

但问题依旧,取出后的时区仍然是UTC。


内容的提问来源于stack exchange,提问作者user842225

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.24 02:52:49