Press "Enter" to skip to content

Lombok, Hibernate, and ‘StackOverflowError: null’ Exception


感觉是不是自己项目配置或者哪里用的不对,就搜了篇标准的JPA 一对多的例子来照抄:

抄完之后,还是不得行,如果去掉JsonIgnore注解,还是会出现 StackOverflowError: null 这个异常,感觉事情不简单,我看了下异常栈,点来点去,感觉可能是我引入的lombok坑了我。我参考的项目没有是 lombok,于是乎我就带这lombok的关键字去搜了下,果然找到了这篇文章:

I really like Project Lombok, with use of this library you can code cleaner, just look at the sample of  @Data (here) and you give me the right!
But after using @Data on an entity, and use it into another entity (eg a Set of comments of a post), throw an ugly error: java.lang.StackOverflowError: null. @Data is a shortcut for these annotations of Lombok:

  • @Getter
  • @Setter
  • @ToString
  • @RequiredArgsConstructor
  • @EqualsAndHashCode

And @EqualsAndHashCode makes this error! I found the solution at last comment of this question on StackOverflow: We should add this line just after at @Data and exclude relational fields from Equals and Hash methods:


I used it on my project, Feader, and you can use it as a sample to check it out ( on develop branch); These are my use case classes, and, FeedEntry use into Feed (like comments and post):

大概意思就是说,Lombok框架虽然好啊,但是容易上头,这个@Data注解如果包含的实体如果被另一个实体引用,就可能丢出来一个栈溢出的异常,导致这个问题的原因是@Data注解包含的@EqualsAndHashCode这个注解。解决的方法很简单,只需要在@Data注解的实体类上加上一个排除那个字段的equals注解就行了,比如你那个字段叫 entries,就加个注解 @EqualsAndHashCode(exclude=”entries”),经过验证确实解决了问题。



public class Book {
    private BookDetail bookDetail;

public class BookDetail {
    private Book book;

you’ve created a cyclic structure. Generated methods like equalshashCode and toString can’t deal with it… and there’s no unique way how they could. They could detect cycles, but this would cost time even for non-cyclic structures. You can exclude a field manually instead.

I always use an ID-based equality, which avoids this sort of problems and many others (and introduces some other problems, I can better live with).

Add @EqualsAndHashCode(exclude="book") to BookDetail, or alike. For other possibilities, look here.

“ID-based equality” means just @EqualsAndHashCode(of="id"). It just says, two objects are equals if they have the same ID. This can be a problem with newly created objects (having no ID yet), etc. It avoids problems with objects changing their state (as the ID never changes, at least for persisted objects) and so changing their hashCode (such a change corrupts any HashMap/Set).

In your case: bookDetail is not something saying “this is a different book”, so I’d exclude it. This is enough to break the cycle.


As of now, the preferred way is

@EqualsAndHashCode.Exclude private BookDetail bookDetail;


您的电子邮箱地址不会被公开。 必填项已用 * 标注