spring - 找到对多对多关系集合的共享引用

标签 spring hibernate jpa

我有这个方法:

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

相关文章:

Java - 获取客户端包中可用接口(interface)的所有实现

java - 如何读取 ENUM 类型的列定义并将其转换为数组\列表

java - Spring JPA - 枚举中枚举字段的默认值

spring - SpringSecurity : Fail to delete JSESSIONID

java - 如何使用 Spring RestOperations 在单元测试中发送 PageRequest 对象?

java - Hibernate 4 + Spring Data CrudRepository,CLI 应用程序 : failed to lazily initialize a collection: could not initialize proxy - no Session

hibernate - hibernate :在HQL中覆盖映射的EAGER?

java - 仅获取 Criteria 查询中的实体 ID

java - Hibernate 无法反序列化错误

jpa - 了解 FetchType.Lazy,强制 JPQL 查询 (OpenJPA)