2 回答
TA贡献1827条经验 获得超8个赞
也许您在服务方法中实现了类似的东西(您没有显示它),但我认为它丢失了:您没有级联任何东西(分别保存另一个类的对象)。您应该将@ManyToMany
注释更改为@ManyToMany(cascade = {CascadeType.PERSIST, CascadeType.MERGE})
. 这会导致级联合并和持久操作(保存新对象或任何更改都会导致自动更新另一个对象)。
更新:基于@Alan Hay 的帖子实施
模型
@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);
}
TA贡献1853条经验 获得超18个赞
这里有两个问题。
首先,您尚未设置关系的级联选项。
@ManyToMany(mappedBy = "movies", cascade = {CascadeType.PERSIST, CascadeType.MERGE}) private List<Actor> actors;
其次,在双向关系的情况下,您有责任在内存模型中维护关系的双方。这里的关系由 Actor(没有 的一方)管理mappedBy
,但您尚未将任何电影添加到 Actor 的电影集合中。
因此,如果您在电影构造函数中迭代演员并添加电影a.getMovies().add(this)
,那么双方都将被设置,并且数据应根据要求保存。
Hibernate 文档建议@ManyToMany
应避免映射,因为在大多数情况下,您可能希望存储与关联相关的其他数据:例如,在您的情况下,角色名称。更灵活的选择是创建一个连接实体,例如 MovieAppearance,它具有 Movie、Actor 和其他所需的属性。
添加回答
举报