JPA,使用@ManyToMany关系时,在连接表中保留重复条目

时间:2011-07-02 16:58:10

标签: jpa many-to-many eclipselink duplicates

我想创建自定义JAAS身份验证,其中我的用户和主体关系在JPA中定义,如下所示:

类AuthUser

public class AuthUser implements Serializable {

    // own properties
    @Id
    @GeneratedValue(strategy=GenerationType.SEQUENCE)
    private int uid;

    @Column(name="NAME",unique=true)
    private String name;

    // Join classes
    @ManyToMany(fetch=FetchType.EAGER,cascade={CascadeType.MERGE})
    @JoinColumn(name="PRINCIPALS_PRINCIPAL")
    private Set<AuthPrincipal> principals;
}

类AuthPrincipal

public class AuthPrincipal implements Serializable {

    // Defining roles
    public enum Principal {
        AUTHUSER, STUDENT, ADMINISTRATOR, TEACHER
    }

    @Id
    @Enumerated(EnumType.STRING)
    @Column(name="PRINCIPAL")
    private Principal principal;

    @ManyToMany(mappedBy = "principals")
    @JoinColumn(name="USERS_USER")
    private Set<AuthUser> users;
}

映射到以下表格定义

Table authprincipal
===================
PRINCIPAL        varchar(255) PK

Table authuser
==============
UID              int(11)      PK
EMAIL            varchar(255)
NAME             varchar(255)
PASSWORD         varchar(255)

Table authuser_authprincipal
============================
users_UID            int(11)      PK
principals_PRINCIPAL varchar(255) PK

现在,我创建了一个JSF文件,我从中调用一个调用此方法的操作方法:

    public void createUser(AuthUser newUser) throws UserNameExistsException, UserEmailExistsException {
    AuthPrincipal role = authRoleFacade.find(AuthPrincipal.Principal.AUTHUSER);
    if( role == null ){
        role = new AuthPrincipal();
        role.setPrincipal(AuthPrincipal.Principal.AUTHUSER);
        authRoleFacade.create(role);
    }    
    authUserFacade.create(newUser);
    addPrincipalToUser(newUser, role);
}

实际问题 我可以创建第一个用户。但我无法创建第二个用户。请注意,在第二个用户,我使用现有的角色对象,并且只是级联合并操作。

最奇怪的是它说它复制了2-AUTHUSER密钥,其中2是新用户的id,因此不能在数据库中。它或Eclipselink或我有什么问题?

eclipselink抛出的错误

Internal Exception: com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Duplicate entry '2-AUTHUSER' for key 'PRIMARY'
Error Code: 1062
Call: INSERT INTO AUTHUSER_AUTHPRINCIPAL (principals_PRINCIPAL, users_UID) VALUES (?, ?)
        bind => [2 parameters bound]
Query: DataModifyQuery(name="principals" sql="INSERT INTO AUTHUSER_AUTHPRINCIPAL (principals_PRINCIPAL, users_UID) VALUES (?, ?)")

1 个答案:

答案 0 :(得分:2)

这完全是我的错。我不够小心:))

1)问题出现是因为我的错,但是,当我只有一个用户时,我不知道为什么错误日志会谈到用户ID 2,但我会说明可能的原因

问题是:我想要保留已经存在的用户。在我的@SessionScoped @ManagedBean中,我在构造函数中创建了AuthUser。在第一次注册时,它持续存在,但我没有创建一个新的。当我想注册下一个我的程序实际执行的操作时:更改已经存在的AuthUser的用户名,电子邮件和密码,并希望再次保留它。

回到1)我可以想象当我第二次调用persist时,Eclipselink实际上持久化我的实体在AuthUser表和连接表中将用户ID更新为2。之后因为我在AuthUser.principals上定义了合并操作,它想再次更新连接表,那就是它搞砸了。如果我仔细查看日志文件中生成的查询,我想我可以自己弄明白。

我在这里得到了提示:http://www.eclipse.org/forums/index.php/m/692056/#msg_692056