JPA坚持不懈

我有一个非常标准的场景,我有一个用户表,其中user_id为PK,一个角色表,其中role_id为PK。 这两个表通过多对多关系相关(即,用户可以有多个角色,一个角色可以应用于许多用户),随后我有一个名为users_has_roles的连接表。 users_has_roles中仅有的两列是users_user_id和roles_role_id。

我已经生成了实体类(见下文),我没有问题将数据持久保存到用户和角色表,但是我很难将任何内容遗留给users_has_roles加入表,因此目前我的所有用户都没有被分配角色。 在我发疯之前,有人可以让我摆脱痛苦,并告诉我应该如何将users_user_id和相应的roles_role_id添加到users_has_roles表中,以便我的用户可以拥有角色?

我的Users.java实体类:

@Entity @Table(name = "users") @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.findByPassword", query = "SELECT u FROM Users u WHERE u.password = :password")}) public class Users implements Serializable { private static final long serialVersionUID = 1L; @Id @Basic(optional = false) @NotNull @Size(min = 1, max = 60) @Column(name = "user_id") private String userId; @Basic(optional = false) @NotNull @Pattern(regexp="[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?", message="Invalid email") @Size(min = 1, max = 45) @Column(name = "username") private String username; @Basic(optional = false) @NotNull @Size(min = 1, max = 120) @Column(name = "password") private String password; @JoinTable(name = "users_has_roles", joinColumns = { @JoinColumn(name = "users_user_id", referencedColumnName = "user_id")}, inverseJoinColumns = { @JoinColumn(name = "roles_role_id", referencedColumnName = "role_id")}) @ManyToMany private Collection rolesCollection; @OneToMany(cascade = CascadeType.ALL, mappedBy = "usersUserId") private Collection userAccountCollection; @OneToMany(cascade = CascadeType.ALL, mappedBy = "usersUserId") private Collection userDetailsCollection; ... All the getter and setter methods etc. 

我的Roles.java实体类:

 @Entity @Table(name = "roles") @XmlRootElement @NamedQueries({ @NamedQuery(name = "Roles.findAll", query = "SELECT r FROM Roles r"), @NamedQuery(name = "Roles.findByRoleId", query = "SELECT r FROM Roles r WHERE r.roleId = :roleId"), @NamedQuery(name = "Roles.findByRoleName", query = "SELECT r FROM Roles r WHERE r.roleName = :roleName"), @NamedQuery(name = "Roles.findByRolePermission", query = "SELECT r FROM Roles r WHERE r.rolePermission = :rolePermission"), @NamedQuery(name = "Roles.findByRoleDescription", query = "SELECT r FROM Roles r WHERE r.roleDescription = :roleDescription")}) public class Roles implements Serializable { private static final long serialVersionUID = 1L; @Id @Basic(optional = false) @NotNull @Size(min = 1, max = 60) @Column(name = "role_id") private String roleId; @Basic(optional = false) @NotNull @Size(min = 1, max = 45) @Column(name = "role_name") private String roleName; @Basic(optional = false) @NotNull @Size(min = 1, max = 45) @Column(name = "role_permission") private String rolePermission; @Size(max = 45) @Column(name = "role_description") private String roleDescription; @ManyToMany(mappedBy = "rolesCollection") private Collection usersCollection; ... All the getter and setter methods etc. 

谢谢

—-更新—-

 // New Users Users currentUser = new Users(); currentUser.setUserId(userId); currentUser.setUsername(email); currentUser.setPassword(password); getUsersFacade().create(currentUser); 

好的,首先感谢Mikko带领我找到答案。 我只是想发布一个答案,可能对我可能处于我所处位置的其他人有直接帮助。这也是基于尤里卡时刻所以它可能在技术上不正确,但这就是我所看到的。

我面临的一个大问题是在MySQL中我可以看到桥接表作为单独的表! (抱歉,我无法发布我的EER图的图像,但我现在似乎没有足够的权限)所以我认为Java也会将桥接表视为一个表! 嗯,它没有。 这个桥接表在Java中并不像传统表那样存在,它实际上由与之关联的对立表集合类型表示。

对我来说最简单的方法是完全忘记桥接表并专注于两个“真实”表并将数据关联起来。 以下代码不是最佳实践,因为我只是设置了role_id,但只是为了表明我的观点。

 List userRoleList = new ArrayList(); Users currentUser = new Users(); currentUser.setUserId(userId); currentUser.setUsername(email); currentUser.setPassword(password); Roles userRole = new Roles(); userRole.setRoleId("2"); userRoleList.add(userRole); currentUser.setRolesCollection(userRoleList); getUsersFacade().create(currentUser); 

希望能帮助任何正在与许多人建立关系的人。

(注意:我已经编辑了原始问题代码以便使用List而不是Collection,但您也可以使用任何其他适合您需求的类型。)

您的示例工作正常(EclipseLink 2.3,MySQL)。 可能的问题是您未显示的部分代码。 例如,在rolesCollection中添加元素。 典型的错误是例如仅将元素添加到非拥有方。

为了保持它,你必须在拥有方面保持关系(一个没有mappedBy),为了保持与数据库一致的内存中对象图,你应该总是修改关系的两面。

我尝试了以下内容:

  // method to add element to rolesCollection public void addRoles(Roles r) { rolesCollection.add(r); } //first created new instances of Users and Roles // then: tx.begin(); users.addRoles(r); //it is not needed for persisting, but here you can also //add user to roles. em.persist(users); em.persist(r); tx.commit();