java - 使用 @JsonIdentityInfo 时空 id 的无限递归
问题描述
我有 2 个 DTO 双向结构Category
,多方关系Product
在哪里。我想将它们作为 JSON 传输到前端层。当 id 已经分配(用于更新操作)时,我没有任何问题,但是当 id 为空(创建)时,我面临着众所周知的无限递归。Product
one-to-many
REST
@JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property="categoryId")
public class CategoryDTO implements Serializable {
private Long categoryId;
private String categoryName;
private List<ProductDTO> products = new LinkedList<>();
public void addProduct(ProductDTO product) {
products.add(product);
product.setCategory(this);
}
// remove synchronization method, setters, getters
}
@JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property="productId")
public class ProductDTO implements Serializable {
private Long productId;
private String productName;
private CategoryDTO category;
// setters, getters
}
但是,当我使用时@JsonManagedReference
,@JsonBackReference
一切都很好。我收到漂亮的 json:
{
"categoryId":null,
"categoryName":"category_name",
"products": [
{
"productId":null,
"productName":"product1"
}
]
}
public class CategoryDTO implements Serializable {
private Long categoryId;
private String categoryName;
@JsonManagedReference
private List<ProductDTO> products = new LinkedList<>();
public void addProduct(ProductDTO product) {
products.add(product);
product.setCategory(this);
}
// remove synchronization method, setters, getters
}
public class ProductDTO implements Serializable {
private Long productId;
private String productName;
@JsonBackReference
private CategoryDTO category;
// setters, getters
}
在这两个示例中,其余部分如下:
@RestController
public class CategoryController {
@GetMapping(path = "/categories")
public ResponseEntity<CategoryDTO> fetchCategories() {
CategoryDTO category = new CategoryDTO();
category.setCategoryName("category_name");
ProductDTO product1 = new ProductDTO();
product1.setProductName("product1");
category.addProduct(product1);
return new ResponseEntity<>(category, HttpStatus.OK);
}
}
为什么@JsonManagedReference
和@JsonBackReference
工作,但@JsonIdentityInfo
不工作?
谢谢阅读。
解决方案
@JsonManagedReference
并且@JsonBackReference
正在使用对象实例引用,因此当您添加Product
到时它可以工作Category
,同时@JsonIdentityInfo
使用字段值中的 id。
答案在课堂上WritableObjectId
和BeanSerializerBase#_serializeWithObjectId(Object, JsonGenerator, SerializerProvider, boolean)
。
换句话说,对于非空字段,序列化程序记得,他序列化了给定的类实例,但他不能对空字段执行此操作。当您点击 endpoint 时,您可以看到这一点/categories
。在连接中断之前,会生成无限的 JSON。
请有人纠正我,如果我错了。
注意: Imo 您应该删除字段private CategoryDTO category
或将其更改为private Long categoryId
,您将摆脱任何注释:D 此外,无限递归也不会有任何问题。
推荐阅读
- apache-spark - 覆盖 Amazon S3 中的特定 Hive 分区目录
- python-3.x - 如何在子图中使用不同的比例
- html - 每当我尝试在 Dream Weaver 中打开某个文件时,都会出现违规错误
- powershell - PowerShell 语法 $using
- c++ - 用于在尾随返回类型中别名模板化结构变量的 Visual C++ 错误 (?)
- javascript - 导出画布后 for 循环显示为空白
- python - 使用 xarray 获取下载数据集(CDS API)的属性和详细信息
- go - Worker Pool 并发模式中何时关闭结果通道?
- c++ - platformIO 中的本机单元测试:ld:未找到架构 x86_64 的符号
- sql - 在 SQLPLUS 中,不能将视图列命名为数字