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

Spring Boot存BitPay数据到PostgreSQL时timestamp为null问题

问题原因
  • timestamp字段存库为null:BitPay接口返回的原始JSON中不存在timestamp字段,RestTemplate反序列化时不会自动给该字段赋值,你也没有手动给该字段设值,最终写入数据库就是null。
  • 手动创建EntityManager报错:Spring Boot引入spring-boot-starter-data-jpa后,已经自动完成了EntityManager、EntityManagerFactory的容器化配置,你手动调用Persistence.createEntityManagerFactory是原生JPA的独立使用方式,脱离了Spring容器管理,才会报找不到持久化提供者的错误,完全不需要手动配置persistence.xml,也不需要自行实例化EntityManager相关对象。
修复方案

1. 补全实体类方法

你的BitPayRates实体类只声明了字段,没有写全各字段的getter、setter方法,Jackson反序列化、JPA操作数据都依赖这些方法访问私有字段,先补全所有字段的getter/setter,同时修正toString方法把timestamp字段加入输出,方便调试。

// 补全所有字段的getter、setter,以下为timestamp字段示例
public LocalDateTime getTimestamp() {
    return timestamp;
}

public void setTimestamp(LocalDateTime timestamp) {
    this.timestamp = timestamp;
}

// id、code、name、rate字段的getter/setter按相同规则补全即可

2. 拉取接口数据后手动赋值时间戳

删掉配置类里注释掉的手动创建EntityManager的无效代码,拿到接口返回的汇率列表后,遍历每条记录给timestamp字段赋值当前时间,再执行存库操作。
修改后的CommandLineRunner代码如下:

@Bean
CommandLineRunner commandLineRunner(BitPayRatesRepo bitPayRatesRepo) {
    return args -> {
        String url = "https://bitpay.com/api/rates";
        RestTemplate restTemplate = new RestTemplate();

        ResponseEntity<List<BitPayRates>> postEntity = restTemplate.exchange(
                url,
                HttpMethod.GET,
                null,
                new ParameterizedTypeReference<>() {}
        );

        List<BitPayRates> results = postEntity.getBody();
        // 统一给本次拉取的所有数据赋值抓取时间
        LocalDateTime fetchTime = LocalDateTime.now();
        results.forEach(rate -> rate.setTimestamp(fetchTime));

        bitPayRatesRepo.saveAll(results);
        System.out.println(results);
    };
}

3. 替换timestamp为主键的注意事项

后续你要把timestamp改为主键时,注意两个问题:

  • 移除原有id字段上的@Id、序列生成器相关注解,将@Id注解加在timestamp字段上
  • LocalDateTime的精度为毫秒级,如果你的接口拉取频率较高,同一毫秒下可能有多条记录,会出现主键冲突问题。建议改用精度更高的Instant类型,或者采用timestamp + code的联合主键,避免冲突。
可选优化
  • 当前控制器返回结果嵌套了两层List,没有实际意义,可以去掉服务层的Collections.singletonList包装,直接返回查询到的汇率列表即可,简化接口结构。
  • 不要在方法内部手动new RestTemplate,建议将其注册为Spring容器管理的Bean,方便后续统一配置连接超时、消息转换器等参数。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 04:45:38