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

Spring Boot如何编写实体类保存嵌套JSON及解决更新ID自增、查询不全问题

问题2:GET接口仅返回顶层字段,无嵌套数据

原因

  • 接口返回类型为父类Model,父类无嵌套关联字段,子类TModel的属性无法被序列化输出。
  • 关联默认是懒加载策略,序列化时关联数据未被初始化,无法输出。
  • 实体类字段名和JSON结构的字段名不匹配(比如实体中tMembers对应JSON中details,memberAttributes对应JSON中mattributes),序列化时字段无法对应。
  • 循环引用导致序列化异常,嵌套字段被忽略。

解决方案

  1. 接口返回类型明确指定为TModel,不要使用父类Model。
  2. 关联注解添加fetch = FetchType.EAGER,或者查询时使用JOIN FETCH主动加载关联数据,避免懒加载未初始化。
  3. 添加@JsonProperty注解匹配JSON字段名,添加@JsonIgnore注解切断循环引用链,添加@JsonIgnoreProperties避免Hibernate代理对象序列化异常。
  4. 所有嵌套层级的实体类(TMemberDetail、MemberAttribute以及内部嵌套的pn、an、p等实体)都要按上述规则配置关联和序列化注解。

修正后核心代码示例

TModel 类

@Setter
@Getter
@Entity
@NoArgsConstructor
@JsonIgnoreProperties({"hibernateLazyInitializer", "handler"})
public class TModel extends Model implements Serializable{
    private static final long serialVersionUID = 7331603514610649855L;

    @OneToMany(mappedBy = "tModel", cascade = CascadeType.ALL, orphanRemoval = true, fetch = FetchType.EAGER)
    @JsonProperty("details")
    private List<TMember> tMembers;
}

TMember 类

@Setter
@Getter
@ToString
@Entity
@NoArgsConstructor
@JsonIgnoreProperties({"hibernateLazyInitializer", "handler"})
public class TMember implements Serializable{
    private static final long serialVersionUID = 7331603514610649855L;
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long tMemberId;

    @ManyToOne(fetch = FetchType.LAZY)
    @JsonIgnore
    private TModel tModel;

    @OneToOne(mappedBy = "tMember", cascade = CascadeType.ALL, orphanRemoval = true, fetch = FetchType.EAGER)
    private TMemberDetail tMemberDetail;

    @OneToOne(mappedBy = "tMember", cascade = CascadeType.ALL, orphanRemoval = true, fetch = FetchType.EAGER)
    @JsonProperty("mattributes")
    private MemberAttribute memberAttributes;
}

基础更新逻辑示例

@Transactional
public TModel updateModel(Long modelId, TModel updateRequest) {
    TModel existingModel = tModelRepository.findById(modelId)
            .orElseThrow(() -> new RuntimeException("指定模型不存在"));
    // 更新顶层属性
    existingModel.setModelName(updateRequest.getModelName());
    existingModel.setModelDescription(updateRequest.getModelDescription());
    existingModel.setRecordStatus(updateRequest.getRecordStatus());
    
    // 处理子成员集合,避免全量替换
    List<TMember> reqMembers = updateRequest.getTMembers();
    // 删除请求中不存在的旧子成员
    existingModel.getTMembers().removeIf(existMem -> 
        reqMembers.stream().noneMatch(reqMem -> Objects.equals(reqMem.getTMemberId(), existMem.getTMemberId()))
    );
    // 新增/更新子成员
    for (TMember reqMem : reqMembers) {
        if (reqMem.getTMemberId() == null) {
            // 新增子成员,绑定父模型关联
            reqMem.setTModel(existingModel);
            existingModel.getTMembers().add(reqMem);
        } else {
            // 更新已有子成员,按需更新属性和下级关联对象
            TMember existMem = existingModel.getTMembers().stream()
                    .filter(m -> m.getTMemberId().equals(reqMem.getTMemberId()))
                    .findFirst().orElseThrow();
            // 此处补充tMemberDetail、memberAttributes的更新逻辑,规则同上
        }
    }
    return tModelRepository.save(existingModel);
}

内容的提问来源于stack exchange,提问作者Pavan Kumar G

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 07:27:03