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?
Advertisement
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