【问题标题】:Spring JPA bi-directional cannot evaluate toStringSpring JPA 双向无法评估 toString
【发布时间】:2016-10-26 15:50:06
【问题描述】:

我已经通过 @JsonIdentityInfothrough 解决了 JSON 递归循环到 Baeldung 的博客1(谢谢)

但是现在,又出现了一个错误:

Method threw 'java.lang.StackOverflowError' exception. Cannot evaluate com.mezoo.tdc.model.Payment.toString()

这里是我的注册对象:

    @Entity
    @Table(name="Registration")
    @JsonIdentityInfo( generator = ObjectIdGenerators.PropertyGenerator.class, property = "uuid")
    public class Registration implements Serializable {

       /*some private variables..*/

      // Bidirectional relationship
      @OneToMany(mappedBy="registration", cascade = {CascadeType.PERSIST, CascadeType.REMOVE, CascadeType.MERGE}, fetch = FetchType.LAZY)
      private List<Payment> payment;

                @Override
      public String toString() {
         return MoreObjects.toStringHelper(this)
            .add("payment", payment)
            .toString();
         }
    }

现在,支付对象:

    @Entity
    @Table(name="Payment")
    @JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "uuid")
    public class Payment implements Serializable {
       @ManyToOne
       @JoinColumn(name = "registration")
       private Registration registration;

       @Override
       public String toString() {
       return MoreObjects.toStringHelper(this)
            .add("registration", registration)
            .toString();
       }
    }

这就是我在调试器中看到的:

请问有什么问题,为什么?

【问题讨论】:

  • 只是IDE的错误(警告)

标签: hibernate spring-data-jpa


【解决方案1】:

删除toString 方法。

如果您使用的是 Lombok:

检查你的 Entity/DAO 类,你可能正在使用来自 lombok@Data 注释,默认情况下包括 getter 和 setter。将其更改为 @Getters@Setter 以备不时之需,并删除 @Data 注释。

【讨论】:

  • 我在使用 @Data 注释并将其删除并将其更改为 @Getters@Setters 并修复。谢谢
  • 正是我想要的。
  • 您可以将导致错误的区域替换为@ToString.Exclude,而不是更改@Data 注释。
  • @Fatih 另一个不错的选择
【解决方案2】:

好吧,我的猜测是Registration.toString() 打印列表中每个付款的字符串表示形式,并且由于Payment.toString() 包含Registration 的字符串表示形式,因此再次调用Registration.toString(),进而调用@987654325再次@,依此类推。

尝试在Payment.toString() 中返回一个空字符串以查看问题是否消失。

【讨论】:

  • 返回一个空字符串解决了这个问题。但是,这意味着 toString 方法现在是多余的。这个问题可以通过更好的 JPA 映射配置来解决吗?我正在为 toString 方法使用 Lombok @Data 注释,这会导致问题吗?
  • 如果我理解正确的话,@Data 暗示@ToString,它会抓取类的所有字段并将它们打印在toString() 中。所以是的,很可能@Data 是这里的问题。至于映射,除非你觉得你不需要双向关联,否则没有什么可改进的,它是完全有效的。产生问题的正是toString() 的生成方式。
  • Lombok 支持排除单个字段添加到自动生成的 toString() 方法。在要从自动生成的 toString() 方法中排除的字段上添加@ToString.Exclude 注释。
【解决方案3】:

在您的Registration.toString() 中,您正在调用Payment.toString(),在您的Payment.toString() 中,您正在调用Registration.toString()

你已经在 toString 中创建了一个循环

  @Override
  public String toString() {
     return MoreObjects.toStringHelper(this)
        .add("payment", payment) //<----------- REMOVE THIS
        .toString();
  }

   @Override
   public String toString() {
   return MoreObjects.toStringHelper(this)
        .add("registration", registration) //<----------- REMOVE THIS
        .toString();
   }

或者更好...删除两者

【讨论】:

    猜你喜欢
    • 2020-12-03
    • 2018-05-07
    • 1970-01-01
    • 2021-07-14
    • 1970-01-01
    • 2016-01-26
    • 1970-01-01
    • 2017-04-06
    • 1970-01-01
    相关资源
    最近更新 更多