Getting errors in getting collection for ManyToMany JPA+Hibernate



I have two classes. A film that keeps authors in it. And the author himself. I want to make the connection ManyToMany for them using EntityManager, where then I can get the data for Set.

Class movie:

@Entity
@Table(name = "MOVIE")
@Data
public class Movie {
  @Id
  private Long id;

  private String movieName;

  @ManyToMany
  @JoinTable(
      name = "movie_authors",
      joinColumns = @JoinColumn(name = "movie_id"),
      inverseJoinColumns = @JoinColumn(name = "author_id"))
  private Set<Author> authors = new HashSet<>();

  public void addAuthor(Author author) {
    authors.add(author);
  }
}

Class author:

@Entity
@Data
public class Author {

  @Id
  private String name;
  @ManyToMany(mappedBy = "authors")
  private Set<Movie> movies = new HashSet<>();
}

Method, where i add authors for movie and push to database:

public void saveMovie() {
    EntityManager em = getEntityManager();

    em.getTransaction().begin();

    Movie movie = new Movie();
    movie.setId(1L);
    movie.setMovieName("The Godfather");

    Author author = new Author();
    author.setName("Privet");
    movie.addAuthor(author);

    Author author1 = new Author();
    author1.setName("Lol");
    movie.addAuthor(author1);

    em.persist(author);
    em.persist(author1);
    em.persist(movie);
    em.getTransaction().commit();
  }

Get movie with authors:

  public Movie getMovie(Long movieId) {
    EntityManager em = getEntityManager();
    Movie movie = em.find(Movie.class, movieId);
    Hibernate.initialize(movie.getAuthors());
    em.detach(movie);
    return movie;
  }

But i get more exceptions:

Exception in thread "main" java.lang.StackOverflowError
    at org.h2.command.Parser.readTerm(Parser.java:4303)
    at org.h2.command.Parser.readFactor(Parser.java:3343)
at Movie.hashCode(Movie.java:9)
    at java.base/java.util.HashMap.hash(HashMap.java:339)
    at java.base/java.util.HashMap.put(HashMap.java:607)
    at java.base/java.util.HashSet.add(HashSet.java:220)
    at java.base/java.util.AbstractCollection.addAll(AbstractCollection.java:352)
    at org.hibernate.collection.internal.PersistentSet.endRead(PersistentSet.java:355)
at Author.hashCode(Author.java:10)
    at java.base/java.util.HashMap.hash(HashMap.java:339)
    at java.base/java.util.HashMap.put(HashMap.java:607)
    at java.base/java.util.HashSet.add(HashSet.java:220)
    at java.base/java.util.AbstractCollection.addAll(AbstractCollection.java:352)

What is wrong?

Answer

I think the Lombok generated hashCode method is causing an infinite loop as Movie references Authors, each of which references the same instance of Movie.

You can probably confirm this by checking bytecode, or just ditch the @Data annotation and manually code equals and hashCode on Entities.

Alternatively you should be able to break the cycle with an @EqualsAndHashCode.Exclude annotation on the movies property of Author – https://projectlombok.org/features/EqualsAndHashCode



Source: stackoverflow