Search code examples
javahibernatejpaspring-data-jpaone-to-one

hibernate| find by id for @OneToOne returns entity in recursion


I Have two entity class Movie and movie cast with one to one relationship when I save them it is saved properly in DB(Postgres)

but when I do find by Id I get recursive/cascading result meaning:

Movie object is having the movie cast and then further internal movie cast is having a movie object which further has movie cast (see below response)

"movieName": "The Shawshank Redemption5",
"creationDateTime": "2023-06-29T20:12:07.379",
"updatedDateTime": "2023-06-29T20:12:07.379",
"releaseDate": "1994-01-01",
"releaseYear": 1997,
"type": "DRAMA",
"movieCasts": {
    "castId": 1,
    "movie": {
        "movieName": "The Shawshank Redemption5",
        "creationDateTime": "2023-06-29T20:12:07.379",
        "updatedDateTime": "2023-06-29T20:12:07.379",
        "releaseDate": "1994-01-01",
        "releaseYear": 1997,
        "type": "DRAMA",
        "movieCasts": {
            "castId": 1,
            "movie": {
                "movieName": "The Shawshank Redemption5",
                "creationDateTime": "2023-06-29T20:12:07.379",
                "updatedDateTime": "2023-06-29T20:12:07.379",
                "releaseDate": "1994-01-01",
                "releaseYear": 1997,
                "type": "DRAMA",
                "movieCasts": {
                    "castId": 1,
                    "movie": {

...... and so on

My Entity class is :

@Data
@Entity
@NoArgsConstructor
public class Movie {

    @Id
    @Column(nullable = false, unique = true)
    private String movieName;

    @Column(nullable = false)
    private LocalDate releaseDate;

    @Column(nullable = false)
    private Integer releaseYear;

    @Enumerated(EnumType.STRING)
    private GENRE type;


    @OneToOne(cascade = {CascadeType.ALL})
   @JoinColumn(name="cast_id",referencedColumnName = "castId")
    private MovieCast movieCasts;

}

And---------------

@Entity
@Data
public class MovieCast {
  @Id
  @GeneratedValue(strategy = GenerationType.SEQUENCE)
  private Long castId;

 // @OneToOne
  @OneToOne(mappedBy = "movieCasts")
  private Movie movie;
  private String director;
  private String producer;
  private  String leadActor;
  private String leadActress;
  private String [] otherActors;
}


@Repository
public class MovieEntityRepo {

    @PersistenceContext
    private EntityManager em;


    public Movie findByName(String name){
        return em.find(Movie.class,name);
    }
}

DB snippet after save

Movies table
movie_name,creation_date,release_date,release_year,type,updation_date,    **cast_id**
The Shawshank Redemption5,2023-06-29 20:12:07.379,1994-01-01,1997,DRAMA,2023-06-29 20:12:07.379,**1**

Movie_cast

cast_id,director,lead_actor,lead_actress,other_actors,producer
1,director1,leader1,leader2,58 bytes,producer1

UPDATING THE Screen shot of actual issue , my issue is not for json but the find method

find method


Solution

  • There are two similar issues with your code. Both result in an infinit loop and stackoverflow.

    1. JSON serialization - this can be solved by adding @JsonIgnore as already explained in another answer.
    2. Java toString() method. Both entities have this method generated by Lombok with @Data annotation.

    Solution

    Add @ToString.Exclude annotation to the Movie field like this:

    @OneToOne(mappedBy = "movieCasts")
    @JsonIgnore
    @ToString.Exclude
    private Movie movie;