如何保持@ManyToMany 关系 - 重复条目或分离实体 [英] How to persist @ManyToMany relation - duplicate entry or detached entity

查看:42
本文介绍了如何保持@ManyToMany 关系 - 重复条目或分离实体的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想用 ManyToMany 关系持久化我的实体.但是我在坚持的过程中遇到了一些问题.

I want to persist my entity with ManyToMany relation. But i have some problem during persisting process.

我的实体:

@Entity
@Table(name = "USER")
public class User implements Serializable {

    private static final long serialVersionUID = 1L;

    @Id
    @Column(name = "ID")
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    Long userId;

    @Column(name = "NAME", unique = true, nullable = false)
    String userName;

    @Column(name = "FORNAME")
    String userForname;

    @Column(name = "EMAIL")
    String userEmail;

    @ManyToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
    @JoinTable(name = "USER_USER_ROLES", joinColumns = @JoinColumn(name = "ID_USER"), inverseJoinColumns = @JoinColumn(name = "ID_ROLE"))
    List<UserRoles> userRoles = new ArrayList<UserRoles>();

    // getter et setter
}

@Entity
@Table(name = "USER_ROLES")
public class UserRoles implements Serializable {

    private static final long serialVersionUID = 1L;

    @Id
    @Column(name = "ID")
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    Long userRolesId;

    @Column(unique = true, nullable = false, name = "ROLE_NAME")
    String roleName; 

    // getter et setter
}

服务代码:

User user = new User();
UserRoles role;
try {
    role = userRolesServices.getUserRoleByName("ROLE_USER"); // find jpql - transaction
} catch (RuntimeException e) {
    LOGGER.debug("No Roles found");
    role = new UserRoles("ROLE_USER"); // create new
}
user.addUserRole(role);
user.setUserName(urlId);
user.setUserForname(fullName);
user.setUserEmail(email);
userServices.createUser(user); // em.persist(user) - transaction

第一次,当我尝试使用 UserRolesROLE_USER"持久化用户时,没问题.插入了 User 和 UserRoles 以及连接表.

First time, when I try to persist a User with UserRoles "ROLE_USER", no problem. User and UserRoles and join tables are inserted.

我的问题是当我尝试保留具有相同 UserRoles 的第二个用户时.我通过查找 UserRoles 来检查它是否存在 (userRolesServices.getUserRoleByName(...)).如果存在 -> 将此 UserRoles 添加到用户列表(id + 角色名称),否则我创建一个新的(仅角色名称).

My problem is when I try to persist a second User with the same UserRoles. I check if the UserRoles exists by finding it (userRolesServices.getUserRoleByName(...)). If exists -> add this UserRoles to User list (id + role name) else i create a new one (only role name).

当我尝试保留第二个用户时,我获得以下异常:要持久化的分离实体:.....UserRoles"(可能是因为在另一个事务中执行了 getUserRoleByName)

By when I try to persist the second User, i obtain the following exception : "detached entity to persist : .....UserRoles" (maybe because getUserRoleByName is performed in another transaction)

如果我不使用 getUserRoleByName(仅 *new UserRoles("ROLE_USER");*),我会得到以下异常:...ConstraintViolation:'ROLE_NAME' 的重复条目..."

If I do not use getUserRoleByName (only *new UserRoles("ROLE_USER");*), i obtain the following exception : "...ConstraintViolation : Duplicated entry for 'ROLE_NAME' ..."

那么,如何正确持久化具有 @ManyToMany 关系的实体?

So, how to properly persist an entity with @ManyToMany relation ?

推荐答案

对于上述问题,我会说您的实体关系级联是错误的.考虑一下:一个用户可以有多个角色,但系统中可以存在固定数量的角色.所以来自 User 实体的 CASCADE ALL 没有任何意义,因为 UserRoles 的生命周期不应该依赖于 User 实体生命周期.例如.当我们删除 User 时,UserRoles 不应该被删除.

For above problem I would say your entity relationship cascade is wrong. Consider this: A user can have multiple roles but there can be fixed number of roles that can exist in the system. So CASCADE ALL from User entity does not make any sense, since life cycle of UserRoles should not depend on User entity life cycle. E.g. when we remove User, UserRoles should not get removed.

要持久化的分离实体异常只会在您传递主键已设置为持久化的对象时发生.

detached entity to persist exception will only occur when you are passing object which has primary key already set to persist.

删除级联,您的问题将得到解决,现在您只需要决定如何插入用户角色.我认为应该有单独的功能来做到这一点.

Remove cascade and your problem will be solved now only thing you will need to decide is how you are going to insert User roles. According to me there should be separate functionality to do so.

同样不要使用ArrayList,使用HashSet.ArrayList 允许重复.

Also do not use ArrayList, use HashSet. ArrayList allows duplicates.

这篇关于如何保持@ManyToMany 关系 - 重复条目或分离实体的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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