2

I have a class

@Entity
@Table(name = "movies")
@Data
public class MovieEntity implements Serializable {
    ...

    @OneToMany(mappedBy = "movie", cascade = CascadeType.ALL)
    private Set<MovieRate> ratings;
}

which maps the list

@Entity
@Table(name = "movies_ratings")
@Data
public class MovieRate {
    ...
}

while loading movie.getRatings() the list throws me out

    ...
at org.eclipse.persistence.indirection.IndirectSet.buildDelegate(IndirectSet.java:225) ~[org.eclipse.persistence.core-2.7.0.jar:na]
    at org.eclipse.persistence.indirection.IndirectSet.getDelegate(IndirectSet.java:436) ~[org.eclipse.persistence.core-2.7.0.jar:na]
    at org.eclipse.persistence.indirection.IndirectSet.hashCode(IndirectSet.java:485) ~[org.eclipse.persistence.core-2.7.0.jar:na]
    at com.core.jpa.entity.MovieEntity.hashCode(MovieEntity.java:21) ~[classes/:na]
    at com.core.jpa.entity.movie.MovieRate.hashCode(MovieRate.java:16) ~[classes/:na]
    at java.util.HashMap.hash(HashMap.java:338) ~[na:1.8.0_144]
    at java.util.HashMap.put(HashMap.java:611) ~[na:1.8.0_144]
    at java.util.HashSet.add(HashSet.java:219) ~[na:1.8.0_144]
    at org.eclipse.persistence.queries.ReadAllQuery.registerResultInUnitOfWork(ReadAllQuery.java:968) ~[org.eclipse.persistence.core-2.7.0.jar:na]
...

All wrong https://pastebin.com/RgNg84Cb

The problem is probably with the Lombok annotations. But I do not know what.

1 Answers1

2

Apparently, the exception is caused by both MovieRate.hashcode() and MovieEntity.hascode() which is generated by Lombok, to solve your issue you may add @EqualsAndHashCode in MovieRate or in MovieEntity or both :

@Entity
@Table(name = "movies")
@Data @EqualsAndHashCode(exclude = "ratings")
public class MovieEntity implements Serializable {
    // Your code
}

or

@Entity
@Table(name = "movies_ratings")
@Data @EqualsAndHashCode(exclude = "movie")
public class MovieRate {
    ...
}

Why? @Data (as it use @EqualsAndHashCode) in order to generate hashCode():

By default, it'll use all non-static, non-transient fields

So it will use MovieEntity.ratings and MovieRate.movie as well, and each call of hashCode() method of the one side will call the other side's hashCode(), and as it's bidirectional association, it will run infinitely till java.lang.StackOverflowError.

Note: You will have the same error for toString() (which also generated by @Data) method for both entities, as each one will attempt to print the other side. To solve it, you can add @ToString to exclude the same fields.

O.Badr
  • 2,853
  • 2
  • 27
  • 36