Spring Boot如何编写实体类保存嵌套JSON及解决更新ID自增、查询不全问题
问题2:GET接口仅返回顶层字段,无嵌套数据
原因
- 接口返回类型为父类
Model,父类无嵌套关联字段,子类TModel的属性无法被序列化输出。 - 关联默认是懒加载策略,序列化时关联数据未被初始化,无法输出。
- 实体类字段名和JSON结构的字段名不匹配(比如实体中
tMembers对应JSON中details,memberAttributes对应JSON中mattributes),序列化时字段无法对应。 - 循环引用导致序列化异常,嵌套字段被忽略。
解决方案
- 接口返回类型明确指定为
TModel,不要使用父类Model。 - 关联注解添加
fetch = FetchType.EAGER,或者查询时使用JOIN FETCH主动加载关联数据,避免懒加载未初始化。 - 添加
@JsonProperty注解匹配JSON字段名,添加@JsonIgnore注解切断循环引用链,添加@JsonIgnoreProperties避免Hibernate代理对象序列化异常。 - 所有嵌套层级的实体类(
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
相关产品推荐
相关产品推荐

