如何插入具有多对多关系的实体? [英] How to insert entity with many to many relation?

查看:91
本文介绍了如何插入具有多对多关系的实体?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用Spring框架.我有两个实体,电影和演员,因此电影可以有许多演员,而演员可以在许多电影中播放.以下是我们的课程:

I'm working with Spring framework. I have two entities, Movie and Actor, so a Movie can have many actors and an Actor can play in many Movie. Following we have the classes:

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;
    }   
}

import java.util.List;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.ManyToMany;

@Entity
public class Movie {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String title;
    private String genre;
    private String year;

    @ManyToMany(mappedBy = "movies")
    private List<Actor> actors;

    public Movie(String title, String genre, String year, List<Actor> actors) {
        this.title = title;
        this.genre = genre;
        this.year = year;
        this.actors = actors;
    }

    public Long getId() {
        return id;
    }

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

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public String getGenre() {
        return genre;
    }

    public void setGenre(String genre) {
        this.genre = genre;
    }

    public String getYear() {
        return year;
    }

    public void setYear(String year) {
        this.year = year;
    }

    public List<Actor> getActors() {
        return actors;
    }

    public void setActors(List<Actor> actors) {
        this.actors = actors;
    }
}

我已经使用@ManyToMany批注定义它们之间的关系.

I have used @ManyToMany annotations to define the relation between them.

这时,我在H2中有一个具有ID,AGE,NAME和SURNAME列的表Actor,具有ID,GENRE,TITLE和YEAR的表Movie和一个新表MOVIE_ACTOR,这是因为带有ACTORS_ID和MOVIES_ID的注释列.到这里为止似乎还不错.

At this point, I have in H2 a table Actor that has ID, AGE, NAME and SURNAME columns, table Movie that has ID, GENRE, TITLE and YEAR, and a new table MOVIE_ACTOR because of the annotation with ACTORS_ID and MOVIES_ID columns. Until here it seems okey.

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

Now, if I save a movie (I have implemented the service and repository extending jpaRepository for both entities):

@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);
    }

(我知道这不是一个get请求,只是为了检查影片是否正确保存而只是访问端点).我得到的是,在Movie表中正确添加了4列,但是ACTOR和MOVIE_ACTOR已完成,因此actorList被省略,这两个表为空.为什么会发生这种情况,我该如何解决?

(I know that it is not a get request, but just for check if a movie is correctly saved just accessing to the endpoint) What I obtain is that in the table Movie the 4 columns are added correctly, but neither ACTOR and MOVIE_ACTOR are completed so actorList is ommited, this two tables are empty. Why this happens and how can I solved it?

非常感谢您的帮助!

推荐答案

也许您在服务方法中实现了类似的操作(未显示),但是我认为它丢失了:您没有层叠任何东西(分别保存另一个类的对象) .您应该将@ManyToMany批注更改为@ManyToMany(cascade = {CascadeType.PERSIST, CascadeType.MERGE}).这导致级联合并和持久操作(保存一个新对象或进行任何更改会导致自动更新另一个对象).

Maybe you implemented something like this in your service methods (you did not show it) but I would assume that it is missing: You do not cascade anything (respectively save objects of the other class). You should change your @ManyToMany annotation to @ManyToMany(cascade = {CascadeType.PERSIST, CascadeType.MERGE}). This leads to cascading the merge and persist operation (saving a new object or any changes leads to automatically updating the other one).

也可以考虑为您的列表添加适当的添加和删除方法,如此

Also consider adding proper add and remove methods for your lists like described in this article and good equals and hashCode methods.

通常,您可以在 Vlad Mihalcea 页面上找到有关Hibernate相关问题的很好描述.. >

更新:基于@Alan Hay发表的实现

型号

In general, you could find very good descriptions of Hibernate related issues on the page of Vlad Mihalcea.

@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 = 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/
}

@Entity
public 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);
}

这篇关于如何插入具有多对多关系的实体?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆