Lombok, Hibernate, and 'StackOverflowError: null' Exception!

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:  https://stackoverflow.com/questions/34972895 We should add this line just after at @Data and exclude relational fields from Equals and Hash methods:

@EqualsAndHashCode(exclude="entries")

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 Feed.java, and FeedEntry.java, FeedEntry use into Feed (like comments and post):

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
package com.glinboy.feader.model;

import java.util.Set;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.Lob;
import javax.persistence.ManyToMany;
import javax.persistence.OneToMany;

import org.hibernate.annotations.Cache;
import org.hibernate.annotations.CacheConcurrencyStrategy;

import lombok.Data;
import lombok.EqualsAndHashCode;

@Entity
@Data
@EqualsAndHashCode(callSuper=true, exclude="entries")
@Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
public class Feed extends BaseModel {

 private static final long serialVersionUID = 7720285113632455831L;
 
 @Column(length=50)
 private String title;
 
 @Column(length=256)
    private String link;
    
    @Lob
    private String description;
 
    @ManyToMany
    @JoinTable(name="feed_category",
      joinColumns = @JoinColumn(name = "feed_id", nullable=false),
            inverseJoinColumns = @JoinColumn(name = "category_id", nullable=false))
    private Set<Category> category;

    @OneToMany(mappedBy="feed")
    private Set<FeedEntry> entries;
}


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
package com.glinboy.feader.model;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.JoinColumn;
import javax.persistence.Lob;
import javax.persistence.ManyToOne;

import lombok.Data;
import lombok.EqualsAndHashCode;

@Entity
@Data
@EqualsAndHashCode(callSuper=true, exclude="feed")
public class FeedEntry extends BaseModel {

 private static final long serialVersionUID = -7086809764656937022L;
 
 @Column(length=128)
 private String title;
 
 @Lob
 private String description;
 
 @Column(length=512)
 private String link;
 
 @Column(length=64)
 private String author;
 
 @Column(length=40)
 private String guid;
 
 @ManyToOne
 @JoinColumn(name="feed_id", nullable=false)
 private Feed feed;
}

Hello World!

Let's start with popular programmer style!
As a Java Developer:
1
2
3
4
5
class Main {
  public static void main(String[] args) {
    System.out.println("Hello world!");
  }
}

As a C++ Programmer:
1
2
3
4
5
6
7
8
#include <iostream>
using namespace std;

int main() 
{
    cout << "Hello, World!";
    return 0;
}

As a Python Developer:
print 'hello world!'

As a fan of Rust:
1
2
3
fn main() {
    println!("Hello World!");
}

As a fan of Go:
1
2
3
4
5
6
7
package main

import "fmt"

func main() {
 fmt.Println("Hello World!")
}

As a fan of Elixir:
IO.puts "Hello, World!"

And Other my friends:
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
{
  "from": "GLinBoy",
  "to": [
    "Developers",
    "Programmers",
    "Geeks",
    "Hackers",
    "Machines",
    "etc"
  ],
  "message": "Hello World!"
}