Ошибка StackOverflowError при попытке вывести список

Получаю ошибку при попытке вывести список Movies(Director->Movies: Один к Многим). В чем может быть причина?

package org.example.model;
        
import lombok.Data;
        
import javax.persistence.*;
import java.util.List;
        
@Data
@Entity
@Table(name = "Direct")
public class Direct {
        
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
        @Column(name = "id")
        private int id;
        @Column(name = "name")
        private String name;
        @OneToMany(mappedBy = "onwer")
        private List<Movies> moviesList;
    }
package org.example.model;
    
import lombok.Data;
    
import javax.persistence.*;
@Data
@Entity
@Table(name = "Movies")
public class Movies {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id")
    private int id;
    
    @Column(name = "title")
    private String title;
   
    @ManyToOne
    @JoinColumn(name = "direct_id", referencedColumnName = "id")
    private Direct onwer;
}
package org.example;
    
import org.example.model.Direct;
import org.example.model.Movies;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
    
import java.util.List;
    
public class App {
    public static void main( String[] args ) {
    
        Configuration configuration = new Configuration().addAnnotatedClass(Direct.class)
                .addAnnotatedClass(Movies.class);
    
        SessionFactory sessionFactory = configuration.buildSessionFactory();
    
        Session session = sessionFactory.getCurrentSession();
        
        try {
            session.beginTransaction();

            Direct direct = session.get(Direct.class, 3);
            System.out.println(direct.getName());
            System.out.println(direct.getId());
    
            List<Movies> movies = direct.getMoviesList();
            System.out.println(movies.toString());

            session.getTransaction().commit();
        } finally {
            session.close();
            sessionFactory.close();
        }
    }
}
    #  (Data source)
    hibernate.driver_class=org.postgresql.Driver
    hibernate.connection.url=jdbc:postgresql://localhost:5432/hiber_demo
    hibernate.connection.username=postgres
    hibernate.connection.password=12345
    
    #  Hibernate
    hibernate.dialect=org.hibernate.dialect.PostgreSQLDialect
    hibernate.show_sql=true
    hibernate.current_session_context_class=thread

введите сюда описание изображения


Ответы (1 шт):

Автор решения: Nowhere Man

Оба класса помечены Lombok-аннотацией @Data, следовательно, в обоих классах переопределён метод toString, при вызове которого и происходит зацикливание: Movie::toString печатает Direct onwer и соответственно вызывает Direct::toString, который печатает список фильмов и для каждого Movie снова вызывает toString.

Для разрыва этой цепочки следует исключить вызов toString, например, при помощи Lombok-аннотации ToString.Exclude для одного или обоих полей:

@Data
@Entity
@Table(name = "Movies")
public class Movies {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id")
    private int id;

    @Column(name = "title")
    private String title;

    @ManyToOne
    @JoinColumn(name = "direct_id", referencedColumnName = "id")
    @ToString.Exclude private Direct onwer;
}

Возможно, также понадобится исключить поля из методов 'equals/hashCode' при помощи аналогичной аннотации @EqualsAndHashCode.Exclude

Аналогичная проблема может возникнуть и при сериализации данных сущностей в JSON, тогда придется использовать аннотации @JsonManagedReference / @JsonBackReference, чтобы избежать зацикливания.

→ Ссылка