Home > OS >  Unable to create a ManyToMany relationship between two entities
Unable to create a ManyToMany relationship between two entities

Time:08-24

I have trouble creating a ManyToMany Relationship between two entities: Actors and Movies. The idea is that movies can have multiple actors and actors can have multiple movies. When I click on a movie, I can see all its actors and when I click on the actor, I can see all the movies that the actor has acted in similar to how IMDB works.

This is my movie class

@Entity
@ToString
@Getter // Both getters and setters are essential in allowing JSON to be converted into a Java Obj
@Setter
@Table(name="MOVIES")
@AllArgsConstructor
@NoArgsConstructor
public class Movie {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Integer id;
    @Column(name="MOVIE_NAME")
    private String movieName;
    @Column(name="YEAR_OF_RELEASE")
    private short yearOfRelease;
    @Column(name="DESCRIPTION")
    private String description;
    @Column(name="RENTAL_COST")
    private double rentalCost;

    @ManyToMany(cascade = CascadeType.ALL)
    @JoinTable(name="movies_actors",
            joinColumns = @JoinColumn(name="movie_id"),
            inverseJoinColumns =@JoinColumn(name="actor_id"))
    private Set<Actor> actors;

    @OneToMany(cascade = CascadeType.ALL)
    private List<UserReview> userReviews;

    // Constructor
    public Movie(
        @JsonProperty("movieName") String movieName,
        @JsonProperty("yearOfRelease") short yearOfRelease,
        @JsonProperty("description") String description,
        @JsonProperty("rentalCost") float rentalCost,
        @JsonProperty("actors") Set<Actor> actors,
        @JsonProperty("userReviews") List<UserReview> userReviews
    )
    {
        this.movieName = movieName;
        this.yearOfRelease = yearOfRelease;
        this.description = description;
        this.rentalCost = rentalCost;
        this.actors = actors;
        this.userReviews = userReviews;
    }

}

This is my actor class

@Entity
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
@ToString
@Table(name="ACTORS")
public class Actor {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)  
    private Integer Id;
    @Column(name="FIRST_NAME")
    private String firstName;
    @Column(name="LAST_NAME")
    private String lastName;
    @Column(name="GENDER")
    private String gender;
    @Column(name="AGE")
    private byte age;

    @JsonIgnore
    @ManyToMany(mappedBy = "actors")
    private List<Movie> movies; 
    
}

Using Postman, my movie object is able to obtain the actors

[
    {
        "movieName": "Happy Feet",
        "yearOfRelease": 2022,
        "description": "A penguin that is happy",
        "rentalCost": 12.0,
        "actors": [
            {
                "firstName": "Tony ",
                "lastName": "Stark",
                "gender": "Male",
                "age": 100,
                "id": 3
            },
            {
                "firstName": "Bruce ",
                "lastName": "Wayne",
                "gender": "Male",
                "age": 33,
                "id": 2
            }
        ],
        "userReviews": [
            {
                "firstName": "Alex",
                "lastName": "Groot",
                "description": "This is a nice movie",
                "rating": 8,
                "movie": null,
                "id": 4
            }
        ],
        "id": 1
    }
]

But when I get the all actors. I am unable to get any movies that the actor acted in and the 'movies' property in the actor obj is also missing.

[
    {
        "firstName": "Bruce ",
        "lastName": "Wayne",
        "gender": "Male",
        "age": 33,
        "id": 2
    },
    {
        "firstName": "Tony ",
        "lastName": "Stark",
        "gender": "Male",
        "age": 100,
        "id": 3
    }
]

How do I fix this such that Movies have the actors list object and actor have the movies list object

CodePudding user response:

@JsonIgnore is the culprit here, it is ignoring the movies list.

I know if you remove jsonIgnore from there you will run into a infinite loops of json. its better that you used a json ignore there.

Instead of returning an Entity object, I suggest return a DTO object only with the data you need. You can get one directly from a Hibernate query/criteria results, using result transformers.

CodePudding user response:

Are you using @JsonIgnore for not persisting the field in the database , or I;m understanding something wrong ? If that is the case, maybe it will be a good idea to replace it with @Transient, which actually does the above job.

  • Related