# Spring Lombok 实体类死循环问题

**URL:** <https://www.isharkfly.com/t/spring-lombok/14129>\
**Category:** 程序语言\
**Tags:** java, spring\
**Created:** [October 2, 2022, 5:05pm UTC](https://www.isharkfly.com/t/spring-lombok/14129 "2022-10-02T17:05:25Z")\
**Posts on this page:** 1\
**Page:** 1

<div class="post-metadata">

**Author:** ![honeymoose](https://www.isharkfly.com/user_avatar/www.isharkfly.com/honeymoose/32/20796_2.png) [@honeymoose](https://www.isharkfly.com/u/honeymoose)\
**Post date:** [October 2, 2022, 5:05pm UTC](https://www.isharkfly.com/t/spring-lombok/14129/1 "2022-10-02T17:05:26Z")

</div>

在 Spring JPA 1 对多查询的时候出现死循环的问题。

如下图所示：

![2022-10-02_13-04-29](https://www.isharkfly.com/images/transparent.png)

所有的配置都是正确的的，就是没有办法获得数据，并且出现死循环

## 问题和解决

因为使用lombak的 @Data ，在toString()方法中产生死循环。

因为我们使用了 @Data 注解。

![2022-10-02_13-04-13](https://www.isharkfly.com/images/transparent.png)

所有让 lombok 定义的 @ToString 类将会实现一个 toString() 方法。

在默认的情况下，将会指向类的名称，同时和每一个字段。

例如在使用 lazy `@OneToMany` 方法调用 hashCode() 的时候，fetch 可能有所有的实体类，这个对应用程序的运行可能产生非常大的性能问题。

同时，如果你在事务以外使用的话，可能会得到 LazyInitializationException 异常。

如果查询一个User实体，并打印，打印调用的是toString() 方法，toString()方法里面又有关联Dept对象。 所以导致 User 和子对象之间的两个对象互相调用并打印，形成一个递归调用，最后堆栈溢出。

基于上面的考虑，我们认为 **`@EqualsAndHashCode` 和`@Data` 不应该应用在 JPA 的实体类上使用** 。

`@ToString` 还是可以使用的，因为我们可以使用 `@ToString.Exclude` 来设置不需要的字段或者使用 `@ToString(onlyExplicitlyIncluded = true` ) 来移除类， 对于 non-lazy 字段，我们可以使用`@ToString.Include` 注解。

例如我们的解决方案就是在 JPA 实体类中只使用

- @Getter
- @Setter

注解。  
 ![2022-10-02_13-14-24](https://www.isharkfly.com/images/transparent.png)

基于上面的原因，这也是很多人建议使用 Lombok 的原因。

我们的理解还是可以使用的，别滥用，别图省事一个 `@Data` 到头。
