0

I have 3 entities Movie, Show and Theatre with below relationship

Relations

 @Entity
@Table(name = "theatre")
public class Theatre {
    @Id
    @Column(name = "id", nullable = false)
    private Long id;

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

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

    @OneToMany(mappedBy = "theatre", orphanRemoval = true)
    private List<Show> shows = new ArrayList<>();

    public List<Show> getShows() {
        return shows;
    }

    public void setShows(List<Show> shows) {
        this.shows = shows;
    }

    public String getTown() {
        return town;
    }

    public void setTown(String town) {
        this.town = town;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }
}


@Entity
@Table(name = "show")
public class Show {
    @Id
    @Column(name = "id", nullable = false)
    private Long id;

    @ManyToOne
    @JoinColumn(name = "theatre_id")
    private Theatre theatre;

    @ManyToOne
    @JoinColumn(name = "movie_id")
    private Movie movie;

    public Movie getMovie() {
        return movie;
    }

    public void setMovie(Movie movie) {
        this.movie = movie;
    }

    public Theatre getTheatre() {
        return theatre;
    }

    public void setTheatre(Theatre theatre) {
        this.theatre = theatre;
    }


    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }
}

@Entity
@Table(name = "movie")
public class Movie {
    @Id
    @Column(name = "id", nullable = false)
    private Long id;

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

    @OneToMany(mappedBy = "movie", orphanRemoval = true)
    private List<Show> shows = new ArrayList<>();

    public List<Show> getShows() {
        return shows;
    }

    public void setShows(List<Show> shows) {
        this.shows = shows;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }
}

Now when I try to fetch list of Theatres for a movie name I'm getting infinite nested result. As a result I'm getting StackOverflow error as well.

Is criteria query not suitable here? Or the relationship is wrong? Or criteria query is wrong itself.

Criteria query

public List<Theatre> findTheatresByMovieAndDate(String movieName) {
        CriteriaBuilder builder = entityManager.getCriteriaBuilder();
        CriteriaQuery<Theatre> query = builder.createQuery(Theatre.class);
        Root<Theatre> fromTheatres = query.from(Theatre.class);
        Join<Theatre, Show> shows = fromTheatres.join("shows");
        Join<Show, Movie> movie = shows.join("movie");

        List<Predicate> conditions = new ArrayList<>();
        conditions.add(builder.equal(movie.get("name"), movieName));


        TypedQuery<Theatre> typedQuery = entityManager.createQuery(query
                .select(fromTheatres)
                .where(conditions.toArray(new Predicate[] {}))
                .orderBy(builder.asc(fromTheatres.get("id")))
                .distinct(true)
        );

        return typedQuery.getResultList();
    }

Thanks in advance

Shubhendu Pramanik
  • 2,711
  • 2
  • 13
  • 23
  • Looks like you can skip theatre-show join as you have theatre stored in the movie already – Antoniossss May 12 '22 at 17:44
  • 1
    Besides are you sure that this is where you have stackoverlow? I would say it could happen if you try to serialize `Theatre` into JSON with all properties as this would create an infinite loop of TheatreX->Show->Movie->TheatreX – Antoniossss May 12 '22 at 17:46
  • 1
    JPA handles the circular references fine, so it won't be JPA causing your error - the stack trace will tell you the tool involved though, but it is common in JSON serialization when you don't specify how relationships should be handled - see https://www.baeldung.com/jackson-bidirectional-relationships-and-infinite-recursion – Chris May 12 '22 at 20:13
  • 1
    Example how to handle bi-directional relationships in Jackson: https://stackoverflow.com/questions/71991102/spring-data-jpa-findall-does-not-return-relations-data/71993222#71993222 – Eugene May 12 '22 at 20:20
  • @Antoniossss yes error occurred on JSON serialization i.e. when returning theatre from REST endpoint. Would it resolve if I create a seperate POJO for theatre and return. Would it be a better design? Apart from this is the relationship between these entities a correct design? – Shubhendu Pramanik May 13 '22 at 01:26
  • Check link provided by Euguene (unless you are not using Jackson)/. Also if you would return TheatreDTO that does not contain its children, you would be fine as well. – Antoniossss May 13 '22 at 07:04

0 Answers0