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

从Java 8迁移至17,将POJO转为Record引发Firestore序列化错误

Java 17 Record与Firestore DocumentSnapshot.toObject() 报错解决方法

问题原因

你遇到的No properties to serialize found错误,是因为当前使用的google-cloud-firestore 3.14.0版本尚未原生支持Java 17的Record类型。Firestore默认序列化机制依赖POJO的getter/setter或可访问字段,而Record的组件通过无前缀的访问方法(如aString1())暴露,且本身是不可变类型,旧版SDK无法识别其结构。

解决方案

方案1:升级Firestore SDK到支持Record的版本

Google Cloud Firestore Java SDK在3.20.0及以上版本中添加了对Java Record的原生支持,升级后无需额外修改即可直接使用toObject(MyRecord.class)。

升级依赖示例(Maven)

修改pom.xml中的依赖版本:

<dependency>
    <groupId>com.google.cloud</groupId>
    <artifactId>google-cloud-firestore</artifactId>
    <version>3.20.0</version> <!-- 推荐使用最新稳定版 -->
</dependency>

升级后,Firestore会自动识别Record的组件,调用其构造方法完成反序列化,同时也支持将Record写入Firestore。

方案2:自定义Firestore数据转换器(无法升级SDK时使用)

如果无法升级SDK,可以实现FirestoreDataConverter接口,手动处理Record与Firestore文档的转换逻辑。

自定义转换器代码

import com.google.cloud.firestore.QueryDocumentSnapshot;
import com.google.cloud.firestore.FirestoreDataConverter;
import java.util.List;
import java.util.Map;

public class MyRecordConverter implements FirestoreDataConverter<MyRecord> {

    @Override
    public MyRecord fromFirestore(QueryDocumentSnapshot snapshot) {
        Map<String, Object> data = snapshot.getData();
        return new MyRecord(
            (String) data.get("aString1"),
            (String) data.get("aString2"),
            (String) data.get("aString3"),
            (String) data.get("aString4"),
            (String) data.get("aString5"),
            (String) data.get("aString6"),
            ((Number) data.get("anInt")).intValue(),
            (Map<String, List<String>>) data.get("services")
        );
    }

    @Override
    public Map<String, Object> toFirestore(MyRecord record) {
        return Map.of(
            "aString1", record.aString1(),
            "aString2", record.aString2(),
            "aString3", record.aString3(),
            "aString4", record.aString4(),
            "aString5", record.aString5(),
            "aString6", record.aString6(),
            "anInt", record.anInt(),
            "services", record.services()
        );
    }
}

使用转换器替换toObject调用

DocumentSnapshot document = future.get();
if (document.exists()) {
    MyRecord myRecord = new MyRecordConverter().fromFirestore((QueryDocumentSnapshot) document);

    if (myRecord != null) {
        fetchData(myRecord);
    }

    return myRecord;
}

额外注意事项

  • 确保Record的组件名称与Firestore文档中的字段名完全一致,若需要映射不同名称的字段,可使用@PropertyName注解(SDK支持后生效,或在转换器中手动处理字段名映射):
    public record MyRecord(
        @PropertyName("string_1") String aString1,
        // 其他字段...
    ) {}
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.12 23:53:28