我有这个方法:
@Override
public Movie createMovie(Movie movie) {
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
JwtUser user = (JwtUser)authentication.getPrincipal();
User current_user = userRepository.findOne(user.getId());
movieRepository.save(movie);
userRepository.save(new HashSet<User>(){{
add(new User(current_user, new HashSet<Movie>(){{
add(movie);
}}));
}});
return movieRepository.save(movie);
}
当我运行我的应用程序并调用该函数时,出现此错误:
Found shared references to a collection: com.movieseat.model.security.User.movies
在我的用户模型中我有:
@ManyToMany
@JoinTable(name = "user_movie",
joinColumns = @JoinColumn(name = "user_id", referencedColumnName = "id"),
inverseJoinColumns = @JoinColumn(name = "movie_id", referencedColumnName = "id")
)
private Set<Movie> movies;
在我的 Movie 模型中我有:
@ManyToMany(mappedBy = "movies", cascade = CascadeType.ALL)
private Set<User> users = new HashSet<>();
public Set<User> getUsers() {
return users;
}
是什么导致了错误?
最佳答案
据我了解您的代码,您正在尝试在数据库中创建一个电影
并将其绑定(bind)到当前的用户
。如果我错了,请纠正我。
首先,你可以从Hibernate User Guide中了解到,双向@ManyToMany 关联应该以不同方式定义和使用。
A bidirectional @ManyToMany association has an owning and a mappedBy side. To preserve synchronicity between both sides, it’s good practice to provide helper methods for adding or removing child entities.
其次,您不应该在@ManyToMany
关联上使用CascadeType.ALL
:
For @ManyToMany associations, the REMOVE entity state transition doesn’t make sense to be cascaded because it will propagate beyond the link table. Since the other side might be referenced by other entities on the parent-side, the automatic removal might end up in a ConstraintViolationException.
For example, if @ManyToMany(cascade = CascadeType.ALL) was defined and the first person would be deleted, Hibernate would throw an exception because another person is still associated with the address that’s being deleted.
因此,我们应该将 cascade
移动到拥有方,更改级联类型,为 User
提供辅助方法并仅更新拥有方(User
) 我们业务逻辑中的关联。让我们更改代码。
用户模型:
@ManyToMany(cascade = {CascadeType.PERSIST, CascadeType.MERGE})
@JoinTable(name = "user_movie",
joinColumns = @JoinColumn(name = "user_id", referencedColumnName = "id"),
inverseJoinColumns = @JoinColumn(name = "movie_id", referencedColumnName = "id")
)
private Set<Movie> movies = new HashSet<>();
public void addMovie(Movie movie) {
movies.add(movie);
movie.getUsers().add(this);
}
public void removeMovie(Movie movie) {
movies.remove(movie);
movie.getUsers().remove(this);
}
电影模特:
@ManyToMany(mappedBy = "movies")
private Set<User> users = new HashSet<>();
和业务逻辑:
@Override
public Movie createMovie(Movie movie) {
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
JwtUser user = (JwtUser)authentication.getPrincipal();
User current_user = userRepository.findOne(user.getId());
current_user.addMovie(movie);
userRepository.save(current_user);
return movie;
}
关于spring - 找到对多对多关系集合的共享引用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47248164/