如何在Gson反序列化JSON时重建双向映射关系?
解决方案
一、使用Gson实现自动维护父实体引用
自定义反序列化器
编写OrderEntity的自定义反序列化器,在基础反序列化完成后,主动为子实体绑定父引用:
public class OrderEntityDeserializer implements JsonDeserializer<OrderEntity> { @Override public OrderEntity deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException { // 先完成常规反序列化 OrderEntity order = context.deserialize(json, OrderEntity.class); // 遍历子实体列表,设置父引用 if (order.getBusinessCart() != null && !order.getBusinessCart().isEmpty()) { for (BusinessCartEntity cartItem : order.getBusinessCart()) { cartItem.setOrderEntity(order); } } return order; } }
注册反序列化器
创建Gson实例时注册上述处理器,后续反序列化即可自动维护关联:
Gson gson = new GsonBuilder() .registerTypeAdapter(OrderEntity.class, new OrderEntityDeserializer()) .create(); // 反序列化示例 OrderEntity order = gson.fromJson(jsonString, OrderEntity.class); // 此时businessCart中每个元素的orderEntity已自动指向当前父实体
二、切换至Jackson库(原生支持双向关联)
Jackson自带双向关联处理能力,通过注解即可同时解决序列化栈溢出和反序列化自动关联的问题:
修改实体类注解
public class OrderEntity { private long id; @OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL) @JoinColumn(name = "order_entity_id") @JsonManagedReference // 标记主动关联,序列化时正常输出 private List<BusinessCartEntity> businessCart = new ArrayList<>(); // Getters & Setters } public class BusinessCartEntity { private long id; @ManyToOne @JsonBackReference // 标记反向关联,序列化时忽略,反序列化时自动绑定父实体 private OrderEntity orderEntity; // Getters & Setters }
使用Jackson序列化/反序列化
ObjectMapper objectMapper = new ObjectMapper(); // 序列化 String json = objectMapper.writeValueAsString(orderEntity); // 反序列化 OrderEntity restoredOrder = objectMapper.readValue(json, OrderEntity.class); // 此时restoredOrder的businessCart子实体已自动关联父对象
三、Gson序列化时保留关联信息(可选)
若希望在序列化阶段传递父实体标识,可给BusinessCartEntity添加非持久化的orderId字段:
public class BusinessCartEntity { private long id; @JsonExclude // 原反向关联字段仍忽略序列化 private OrderEntity orderEntity; private long orderId; // 仅用于序列化传递父实体ID // Getters & Setters }
序列化OrderEntity前,遍历businessCart为每个子实体设置orderId;反序列化时,先还原OrderEntity,再遍历子实体通过orderId匹配并绑定父引用。该方式步骤繁琐,仅在特殊场景下适用。
内容的提问来源于stack exchange,提问作者Saron Ciupe
相关产品推荐
相关产品推荐

