是否可以避免 OneToMany-ManyToOne 双向关系中的递归和 StackOverflowError?

Is it possible to avoid recursion and StackOverflowError in OneToMany-ManyToOne bi-directional relations?

我使用 Spring Boot 和 Thymeleaf 创建 Web 应用程序。

当我调试我的应用程序时,它运行得非常慢。每个 F8 步,调试器都会在我的对象上显示消息 "Collecting data..."。而且我很长时间(10-60秒)都看不到我对象的状态。

最后,当收集数据完成时,我看到 WhosebugError

我了解在这种情况下存在无限递归。 Car 链接到 Service,Service 链接到 Car,等等。它会溢出每个对象的 toString() 方法。

我看到很多使用 @OneToMany@ManyToOne 注释的例子。所有这些都会导致此递归和 WhosebugError。在这种情况下,工程师建议放置 @JsonIgnore@JsonManagedReference/@JsonBackReference 注释来修复无限递归。

这些建议适用于 REST API 序列化对象。

问题是 我没有开发 REST API。我制作 Web MVC 应用程序

那么你能推荐我什么来修复这个递归并拥有一个快速调试的应用程序?

这是一个糟糕的设计吗?或者别的什么?

谢谢

我在debug的时候没有遇到过这样的问题,我觉得这跟你的设计关系比较大。 但是尝试添加 LAZY,例如:

@ManyToOne(fetch = FetchType.LAZY)

这会有所帮助。

问题的有效解决方案:

  1. 首先需要标记@ManyToOne(fetch = FetchType.LAZY)注解才能在调试时有更好的性能

  2. 第二件事是修改标准IDE-generatedtoString方法。对于嵌套对象,您应该 return 不是整个对象,而只是一个对象 ID。

Service 示例:

修改前:

@Override
  public String toString() {
    return "Service{" +
        "serviceId=" + serviceId +
        ", car=" + car +
        ", event='" + event + '\'' +
        ", created=" + created +
        ", modified=" + modified +
        '}';
  }

修改后:

@Override
  public String toString() {
    String carId;
    if (car == null) {
      carId = "null";
    } else {
      carId = car.getCarId().toString();
    }
    return "Service{" +
        "serviceId=" + serviceId +
        ", carId=" + carId +
        ", event='" + event + '\'' +
        ", created=" + created +
        ", modified=" + modified +
        '}';
  }

现在我没有收到调试器 "Collecting data..." 消息和 WhosebugError 异常。

调试性能不错!