如何插入具有多对多关系的实体?

我正在使用 Spring 框架。我有两个实体,电影和演员,所以一部电影可以有很多演员,一个演员可以在很多电影中扮演。接下来我们有课程:


import java.util.List;


import javax.persistence.Entity;

import javax.persistence.GeneratedValue;

import javax.persistence.GenerationType;

import javax.persistence.Id;

import javax.persistence.JoinTable;

import javax.persistence.ManyToMany;


@Entity

public class Actor {


    @Id

    @GeneratedValue(strategy = GenerationType.IDENTITY)

    private Long id;

    private String name;

    private String surname;

    private String age;


    @ManyToMany

    @JoinTable(name = "movie_actor")

    private List<Movie> movies;


    public Actor(String name, String surname, String age) {

        this.name = name;

        this.surname = surname;

        this.age = age;

    }


    public Long getId() {

        return id;

    }


    public void setId(Long id) {

        this.id = id;

    }


    public String getName() {

        return name;

    }


    public void setName(String name) {

        this.name = name;

    }


    public String getSurname() {

        return surname;

    }


    public void setSurname(String surname) {

        this.surname = surname;

    }


    public String getAge() {

        return age;

    }


    public void setAge(String age) {

        this.age = age;

    }


    public List<Movie> getMovies() {

        return movies;

    }


    public void setMovies(List<Movie> movies) {

        this.movies = movies;

    }   

}

我使用@ManyToMany注释来定义它们之间的关系。


此时,我在 H2 中有一个具有 ID、AGE、NAME 和 SURNAME 列的 Actor 表,具有 ID、GENRE、TITLE 和 YEAR 的表 Movie,以及一个新表 MOVIE_ACTOR,因为带有 ACTORS_ID 和 MOVIES_ID 列的注释。直到这里看起来还可以。


现在,如果我保存一部电影(我已经为两个实体实现了扩展 jpaRepository 的服务和存储库):


@GetMapping("/create")

public void create() {

        Actor actor1 = new Actor("Pedro", "Perez", "40");

        Actor actor2 = new Actor("Alfredo", "Mora", "25");

        Actor actor3 = new Actor("Juan", "Martinez", "20");

        Actor actor4 = new Actor("Mario", "Arenas", "30");

    }

(我知道这不是一个获取请求,只是为了检查电影是否正确保存,只需访问端点)我得到的是,在表 Movie 中,4 列已正确添加,但 ACTOR 和 MOVIE_ACTOR 均未完成所以省略了 actorList,这两个表是空的。为什么会发生这种情况以及如何解决?


鸿蒙传说
浏览 92回答 2
2回答

斯蒂芬大帝

也许您在服务方法中实现了类似的东西(您没有显示它),但我认为它丢失了:您没有级联任何东西(分别保存另一个类的对象)。您应该将@ManyToMany注释更改为@ManyToMany(cascade = {CascadeType.PERSIST, CascadeType.MERGE}). 这会导致级联合并和持久操作(保存新对象或任何更改都会导致自动更新另一个对象)。更新:基于@Alan Hay 的帖子实施模型@Entitypublic class Actor {    @Id    @GeneratedValue(strategy = GenerationType.IDENTITY)    private Long id;    private String name;    private String surname;    private String age;    @ManyToMany    @JoinTable(name = "movie_actor")    private List<Movie> movies = new ArrayList<>();    public void addMovie(Movie movie) {        movies.add(movie);        movie.getActors().add(this);    }    public void removeMovie(Movie movie) {        movies.remove(movie);        movie.getActors().remove(this);    }    // Constructors, getters and setters...    // Equals and hashCode methods a la     // https://vladmihalcea.com/how-to-implement-equals-and-hashcode-using-the-jpa-entity-identifier/}@Entitypublic class Movie {    @Id    @GeneratedValue(strategy = GenerationType.IDENTITY)    private Long id;    private String title;    private String genre;    private String year;    @ManyToMany(mappedBy = "movies", cascade = {CascadeType.PERSIST, CascadeType.MERGE})    private List<Actor> actors;    public Movie(String title, String genre, String year, List<Actor> actors) {        this.title = title;        this.genre = genre;        this.year = year;        actors.forEach(a -> a.addMovie(this));    }    // Getters and setters...}创建方法@GetMapping("/create")public void create() {    Actor actor1 = new Actor("Pedro", "Perez", "40");    Actor actor2 = new Actor("Alfredo", "Mora", "25");    Actor actor3 = new Actor("Juan", "Martinez", "20");    Actor actor4 = new Actor("Mario", "Arenas", "30");    List<Actor> actorList = new ArrayList<>();    actorList.add(actor1);    actorList.add(actor2);    actorList.add(actor3);    actorList.add(actor4);    Movie movie = new Movie("Titanic", "Drama", "1984", actorList);    movieService.create(movie);}

慕容森

这里有两个问题。首先,您尚未设置关系的级联选项。@ManyToMany(mappedBy&nbsp;=&nbsp;"movies",&nbsp;cascade&nbsp;=&nbsp;{CascadeType.PERSIST,&nbsp;CascadeType.MERGE}) private&nbsp;List<Actor>&nbsp;actors;其次,在双向关系的情况下,您有责任在内存模型中维护关系的双方。这里的关系由 Actor(没有 的一方)管理mappedBy,但您尚未将任何电影添加到 Actor 的电影集合中。因此,如果您在电影构造函数中迭代演员并添加电影a.getMovies().add(this),那么双方都将被设置,并且数据应根据要求保存。Hibernate 文档建议@ManyToMany应避免映射,因为在大多数情况下,您可能希望存储与关联相关的其他数据:例如,在您的情况下,角色名称。更灵活的选择是创建一个连接实体,例如 MovieAppearance,它具有 Movie、Actor 和其他所需的属性。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Java