当尝试序列化具有自引用关系的 DTO 类 (NodeAttributesDTO) 时,我在 Spring Boot 应用程序中遇到 StackOverflowError。错误发生在执行DTO类中的toString方法时。
NodeAttributes.java:
// Relevant parts of NodeAttributes.java
@OneToMany(mappedBy = "parent")
@Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
@JsonIgnoreProperties(value = { "children", "parent", "node" }, allowSetters = true)
private Set<NodeAttributes> children ;
@ManyToOne
@JsonIgnoreProperties(value = { "children", "parent", "node" }, allowSetters = true)
private NodeAttributes parent;
// Other fields, getters, setters, etc.
NodeAttributesDTO.java:
// Relevant parts of NodeAttributesDTO.java
private Set<NodeAttributesDTO> children;
private NodeAttributesDTO parent;
// Getters, setters, and other methods...
@Override
public String toString() {
return "NodeAttributesDTO{" +
"id=" + getId() +
// Other fields...
", parent=" + getParent() +
", children=" + getChildren() +
", node=" + getNode() +
"}";
}
PostMapping 请求正文:
{
// Some other fields...
"children": [
{
"key": "attribute412w",
"value": "value3",
"valueType": "Integer",
"type": "RESPONSE",
"required": false,
"enabled": true,
"node": {
"id": 26030
}
}
],
// Other fields...
}
错误:
{
"type": "https://www.jhipster.tech/problem/problem-with-message",
"title": "Internal Server Error",
"status": 500,
"detail": "Handler dispatch failed; nested exception is java.lang.StackOverflowError",
"path": "/api/node-attributes",
"message": "error.http.500"
}
问题:
环境: 春季启动版本:2.7.2 Java版本:17 数据库:Postgresql
我已经尝试过:
我相信您的困惑是 toString 不控制 Spring Boot 中的编组。
如果您要通过 System.err.println() 记录该对象以表示标准错误,它将使用 toString。
似乎您的 toString 本质上是试图成为数据的递归转储,但并不正确。我认为这只是基本的 Java/CS。
在toString中,您可以只打印当前节点的数据,然后对所有子节点调用toString(delagate)。应该可以做到这一点。我认为一般情况下您不需要反向引用(对于 toString),因为您将从“树”的顶部开始。
编组器检查对象并使用反射来组成序列化表示。正如您所注意到的,它将遵守某些注释。比如@JsonIgnore。
看到这个:如何忽略 json 响应中的字段?
这里有很多好信息:https://www.baeldung.com/jackson
它还可能有助于在代码生成工具(如 jhipster)之外创建一个简单的 Web 服务,以了解幕后发生的情况,从而更好地控制生成。