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

Spring Boot使用MongoRepository存储动态JSON到MongoDB的结构调整问题

问题原因

你当前的实体类中product是独立的Map类型字段,Spring Data MongoDB默认会将其序列化为嵌套对象存储,因此会多出一层product结构。

解决方法

这里提供两种兼容动态字段需求的实现方案:


方案1:使用@Unwrapped注解(改动最小)

Spring Data MongoDB 3.2及以上版本提供了@Unwrapped注解,可直接将嵌套字段的属性平铺到文档根层级,只需修改Product实体类即可:

import org.springframework.data.mongodb.core.mapping.Document;
import org.springframework.data.mongodb.core.mapping.Unwrapped;
import org.springframework.data.annotation.Id;
import java.util.Map;
import java.util.HashMap;

@Document
public class Product {

    @Id
    private String id;
    
    @Unwrapped(onEmpty = Unwrapped.OnEmpty.USE_NULL)
    private Map<String,Object> product;

    public Product(){
        this.product = new HashMap<>();
    }
    
    public void setProduct(Map<String,Object> product){
        this.product = product;
    }
    
    public Map<String, Object> getProduct(){
        return this.product;
    }
    
    // id的getter、setter
    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }
}

修改后原有控制器逻辑不需要做任何调整,存储时会自动将product Map内的所有键值对平铺到根层级。


方案2:手动转换存储(兼容性最好)

如果你使用的Spring Data MongoDB版本低于3.2,或者不想依赖特定注解,可以通过手动转换的方式实现,逻辑更透明:

  1. 首先修改Product实体类,继承HashMap以支持动态字段:
import org.springframework.data.mongodb.core.mapping.Document;
import org.springframework.data.annotation.Id;
import java.util.HashMap;

@Document
public class Product extends HashMap<String, Object> {
    @Id
    private String id;

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }
}
  1. 调整控制器代码,将请求中product节点的属性直接放入Product对象:
@PostMapping("/product")
public void FeedConsume(@RequestBody Map<String, Object> requestBody, @RequestParam(value = "site_name") String siteName, @RequestParam(value = "site_key") String siteKey){
    Map<String, Object> productAttrs = (Map<String, Object>) requestBody.get("product");
    Product product = new Product();
    product.putAll(productAttrs);
    productRepo.save(product);
}

这种方式完全兼容任意数量的动态字段,不需要额外的序列化配置。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.01 20:57:03