java - 如何停止 @ManyToOne JPA 中的重复对象?

标签 java json hibernate spring-boot jackson

我的家长类(class):

@OneToMany(mappedBy = "parent", cascade = CascadeType.ALL)
private List<Child> child;

public List<Child> getChild() {
    return child;
}

public void setChild(List<Child> child) {
    this.child = child;
}

我的 child 类(class):

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "REF_ID")
private Parent parent;

public Parent getParent() {
    return parent;
}

public void setParent(Parent parent) {
    this.parent = parent;
}

错误:

Caused by: java.lang.IllegalStateException: getOutputStream() has already been called for this response
at org.apache.catalina.connector.Response.getWriter(Response.java:626) ~[tomcat-embed-core-8.5.15.jar:8.5.15]
at org.apache.catalina.connector.ResponseFacade.getWriter(ResponseFacade.java:211) ~[tomcat-embed-core-8.5.15.jar:8.5.15]
at javax.servlet.ServletResponseWrapper.getWriter(ServletResponseWrapper.java:109) ~[tomcat-embed-core-8.5.15.jar:8.5.15]
at org.springframework.boot.autoconfigure.web.ErrorMvcAutoConfiguration$SpelView.render(ErrorMvcAutoConfiguration.java:227) ~[spring-boot-autoconfigure-1.5.4.RELEASE.jar:1.5.4.RELEASE]
at org.springframework.web.servlet.DispatcherServlet.render(DispatcherServlet.java:1286) ~[spring-webmvc-4.3.9.RELEASE.jar:4.3.9.RELEASE]
at org.springframework.web.servlet.DispatcherServlet.processDispatchResult(DispatcherServlet.java:1041) ~[spring-webmvc-4.3.9.RELEASE.jar:4.3.9.RELEASE]
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:984) ~[spring-webmvc-4.3.9.RELEASE.jar:4.3.9.RELEASE]
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:901) ~[spring-webmvc-4.3.9.RELEASE.jar:4.3.9.RELEASE]
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:970) ~[spring-webmvc-4.3.9.RELEASE.jar:4.3.9.RELEASE]
... 38 common frames omitted

在浏览器中:

enter image description here

它看起来像来自父实体的 @OneToMany 调用子对象很好。但是子实体中的 @ManyToOne 通过再次调用父对象并重复来执行相同的操作。如何避免这个问题?

最佳答案

我会使用@JsonManagedReference@JsonBackReference像这样:

父级

@JsonBackReference
@OneToMany(mappedBy = "parent", cascade = CascadeType.ALL)
private List<Child> child;

子项

@JsonManagedReference
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "REF_ID")
private Parent parent;

发生了什么?

这与JPA无关。您的 @Entity 模型提供了访问字段的方法。要在 API 中表示它们,您需要将它们序列化。序列化器不知道该级别的实体(它会了解持久层。这将违反 SRP )。因此,您必须提供序列化程序提示,就像在实体模型上使用 @ManyToOne、@OneToMany 一样。序列化器遍历类上的 get 方法并调用它们。如果没有提示,您最终会得到循环引用,因为您调用父级,然后获取子级。序列化子级后,您将再次调用父级。

来自引用文献

@JsonManagedReference :注解,用于指示带注解的属性是字段之间双向链接的一部分;并且其角色是“父”(或“转发”)链接。

@JsonBackReference :用于指示关联属性是字段之间双向链接的一部分的注释;它的角色是“子”(或“后”)链接

关于java - 如何停止 @ManyToOne JPA 中的重复对象?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45551631/

相关文章:

Java:Web 应用程序中的 hibernate - 无法实例化默认 tuplizer [org.hibernate.tuple.entity.PojoEntityTuplizer]

java - Jackson ObjectMapper 如何将 byte[] 传输到 String 以及如何在没有对象类的情况下翻译它?

java - MVP 模式在哪里处理 Textview?

java - 如何在 tomcat 8 嵌入式 javascript/json/java webapp 上启用 ssl

java - 在不使用注释的情况下反序列化具有接口(interface)属性的 JSON 类

java - hibernate spring简单单元测试读取数据。 findAll() 无法引用

java - Null 安全检查和 if 条件优先级

javascript - 获取本地 JSON

javascript - 将日期字符串转换为 JSON 日期格式

java - 在 JPA 中使用两个或多个参数的搜索查询