JPA中的多对多关系与连接表

时间:2013-09-23 08:59:10

标签: jpa many-to-many

我正在尝试使用连接表创建实体。我有实体用户和组。在数据库中我有另一个表用户组。当我将用户添加到组并保存新的条目时,在组表中创建。可能是什么错误?

用户实体:

@Entity
@Table(schema = "useradministration")
@XmlRootElement
@NamedQueries({
    @NamedQuery(name = "Users.findAll", query = "SELECT u FROM Users u"),
    @NamedQuery(name = "Users.findByUserid", query = "SELECT u FROM Users u WHERE u.userid = :userid"),
    @NamedQuery(name = "Users.findByUsername", query = "SELECT u FROM Users u WHERE u.username = :username"),
    @NamedQuery(name = "Users.findByUserpassword", query = "SELECT u FROM Users u WHERE u.userpassword = :userpassword"),
    @NamedQuery(name = "Users.findByFirstname", query = "SELECT u FROM Users u WHERE u.firstname = :firstname"),
    @NamedQuery(name = "Users.findByMiddlename", query = "SELECT u FROM Users u WHERE u.middlename = :middlename"),
    @NamedQuery(name = "Users.findByLastname", query = "SELECT u FROM Users u WHERE u.lastname = :lastname")})
public class Users implements Serializable {

    private static final long serialVersionUID = 1L;
    @Id
    @SequenceGenerator(name = "useradministration.users_userid_seq",
            sequenceName = "useradministration.users_userid_seq",
            allocationSize = 1)
    @GeneratedValue(strategy = GenerationType.SEQUENCE,
            generator = "useradministration.users_userid_seq")
    @Basic(optional = false)
    @Column(nullable = false)
    private Integer userid;
    @Size(max = 50)
    @Column(length = 50)
    private String username;
    @Size(max = 200)
    @Column(length = 200)
    private String userpassword;
    @Size(max = 100)
    @Column(length = 100)
    private String firstname;
    @Size(max = 100)
    @Column(length = 100)
    private String middlename;
    @Size(max = 100)
    @Column(length = 100)
    private String lastname;
    @ManyToMany(cascade = {CascadeType.MERGE, CascadeType.PERSIST, CascadeType.REFRESH}, fetch = FetchType.EAGER)
    @JoinTable(name = "useradministration.usergroups",
            joinColumns = {
        @JoinColumn(name = "userid", referencedColumnName = "userid", nullable = false)
    },
            inverseJoinColumns = {
        @JoinColumn(name = "groupid", referencedColumnName = "groupid", nullable = false)})
    private List<Groups> groupsList;


@Override
public int hashCode() {
    int hash = 0;
    hash += (userid != null ? userid.hashCode() : 0);
    return hash;
}

@Override
public boolean equals(Object object) {
    // TODO: Warning - this method won't work in the case the id fields are not set
    if (!(object instanceof Users)) {
        return false;
    }
    Users other = (Users) object;
    if ((this.userid == null && other.userid != null) || (this.userid != null && !this.userid.equals(other.userid))) {
        return false;
    }
    return true;
}

@Override
public String toString() {
    return "com.cell.user.Users[ userid=" + userid + " ]";
}

群组实体:

@Entity
@Table(schema = "useradministration")
@XmlRootElement
@NamedQueries({
    @NamedQuery(name = "Groups.findAll", query = "SELECT g FROM Groups g"),
    @NamedQuery(name = "Groups.findByGroupid", query = "SELECT g FROM Groups g WHERE g.groupid = :groupid"),
    @NamedQuery(name = "Groups.findByGroupname", query = "SELECT g FROM Groups g WHERE g.groupname = :groupname"),
    @NamedQuery(name = "Groups.findByGroupdesc", query = "SELECT g FROM Groups g WHERE g.groupdesc = :groupdesc")})
public class Groups implements Serializable {

    private static final long serialVersionUID = 1L;
    @Id
    @SequenceGenerator(name = "useradministration.groups_groupid_seq",
            sequenceName = "useradministration.groups_groupid_seq",
            allocationSize = 1)
    @GeneratedValue(strategy = GenerationType.SEQUENCE,
            generator = "useradministration.groups_groupid_seq")
    @Basic(optional = false)
    @Column(nullable = false)
    private Integer groupid;
    @Size(max = 50)
    @Column(length = 50)
    private String groupname;
    @Size(max = 200)
    @Column(length = 200)
    private String groupdesc;
    @ManyToMany(cascade = {CascadeType.MERGE, CascadeType.PERSIST, CascadeType.REFRESH})
    @JoinTable(name = "useradministration.usergroups",
            joinColumns = {
        @JoinColumn(name = "groupid", referencedColumnName = "groupid", nullable = false)
    },
            inverseJoinColumns = {
        @JoinColumn(name = "userid", referencedColumnName = "userid", nullable = false)})

    private List<Users> usersList;


@Override
public int hashCode() {
    int hash = 0;
    hash += (groupid != null ? groupid.hashCode() : 0);
    return hash;
}

@Override
public boolean equals(Object object) {
    // TODO: Warning - this method won't work in the case the id fields are not set
    if (!(object instanceof Groups)) {
        return false;
    }
    Groups other = (Groups) object;
    if ((this.groupid == null && other.groupid != null) || (this.groupid != null && !this.groupid.equals(other.groupid))) {
        return false;
    }
    return true;
}

@Override
public String toString() {
    return "com.cell.user.Groups[ groupid=" + groupid + " ]";
}

在Usercontroller中添加用户代码:

public void addUser() {
        List<Groups> groupList = new ArrayList<>();
        for (String s : usergroups) {
            groupList.add(usercontrollerEJB.getGroup(Integer.parseInt(s)));
        }
        user.setGroupsList(groupList);
       //hash some password here
        String hashedPassword = Utility.hashPasswordSHABase64(user.getUserpassword());

        try {
           // aeshedPassword = Utility.encrypt(hashedPassword, key);
           // user.setUserpassword(aeshedPassword);
            user.setUserpassword(hashedPassword);
            usercontrollerEJB.addUser(user);
            user = new Users();
            usergroups = new ArrayList<>();
        } catch (Exception ex) {
            Logger.getLogger(UserController.class.getName()).log(Level.SEVERE, null, ex);
        }


    }

usercontrollerejb中的代码:

public void addUser(Users user) {
        em.persist(user);
    }

当我向用户添加组时,它会尝试插入组表:

INSERT INTO useradministration.GROUPS (GROUPID, GROUPDESC, GROUPNAME) VALUES (?, ?, ?)
    bind => [1, Administration, Admin]

1 个答案:

答案 0 :(得分:0)

当通过JPA创建关系时,实体的一方必须被定义为拥有方,但是在提供的代码中,似乎@ManyToMany的两边都被表示为关系的拥有方。关系的拥有方由@JoinColumn注释的位置表示。

尝试修改Group实体以使用mappedBy注释上的@ManyToMany元素:

    public class Groups implements Serializable {
        //omitted code
        @ManyToMany(mappedBy="groupsList" cascade = {CascadeType.MERGE, CascadeType.PERSIST, CascadeType.REFRESH})
        private List<Users> usersList;
        //omitted code
}

另请记住,您有责任管理关系的双方,这意味着如果您将GroupList分配给User,则还必须在User上设置GroupList }。

    List<Groups> groupList = new ArrayList<>();
    for (String s : usergroups) {
        groupList.add(usercontrollerEJB.getGroup(Integer.parseInt(s)));
    }
    groupList.getUserList().add(user); //add this
    user.setGroupsList(groupList);