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

问题描述

enter image description here

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

当我调试应用程序时,它的运行速度非常慢。调试器的每个F8步骤在我的对象上显示消息“正在收集数据...” 。而且很长时间(10-60秒)都看不到对象的状态。

enter image description here

最后,完成数据收集后,我看到 StackOverflowError

enter image description here

我了解在这种情况下存在无限递归。汽车链接到服务,服务链接到汽车,等等。并且它会为每个对象溢出toString()方法。

我看到了许多使用@OneToMany@ManyToOne注释的示例。所有这些都会导致此递归和StackOverflowError。并且在这种情况下,工程师建议放置@JsonIgnore@JsonManagedReference / @JsonBackReference批注以修复无限递归。

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

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

那么您能推荐我些什么来解决此递归问题并拥有一个快速调试的应用程序?

设计不好吗?还是其他?

谢谢

解决方法

我在调试过程中没有遇到此类问题,我认为这与您的设计更相关。 但是,请尝试添加LAZY,例如:

@ManyToOne(fetch = FetchType.LAZY)

这可能会有所帮助。

,

该问题的有效解决方案:

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

  2. 第二件事是修改标准的IDE生成的toString方法。对于嵌套对象,您不应返回整个对象,而应返回一个对象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 +
        ",modified=" + modified +
        '}';
  }

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

调试性能很好!

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...