JPA 在列出类的所有实体时返回同一实例的多个对象

标签 jpa persistence db2

我有一个带有子实体列表的 JPA 实体。在本例中是一个附加有角色的用户实体。

它看起来(有点简化 - 省略了一些字段/方法)像这样:

@Entity
public class MyUser{

 @Id
 @GeneratedValue(strategy = GenerationType.IDENTITY)
 private Long myUserId;

 private String username; 

 @OneToMany
 @JoinTable(name = "userrole",
   joinColumns = {
     @JoinColumn(name="myUserId", unique = true)           
   },
   inverseJoinColumns = {
     @JoinColumn(name="roleId")
   }
 )
 private Collection<Role> roles;    

 public Collection<Role> getRoles() {
     return roles;
 }
}

如果有趣的话,Role 实体非常简单。

@Entity
public class Role {
  @Id
  @GeneratedValue(strategy = GenerationType.IDENTITY)
  private Long roleId;
  private String role; // a few more string fields here .

当我添加两个用户并为每个用户添加数百个角色时,在列出用户时会出现奇怪的行为。每个用户都会被列出几百次(相同的用户 = 相同的唯一 ID)。

有问题的代码:

Query q = em.createQuery("SELECT u FROM MyUser u LEFT JOIN FETCH u.roles");
Collection<MyUser> users = q.getResultList();

for(MyUser u : users){
     // print/use u here
} 

但是,当我刚刚访问数据库并执行 select 语句时,看起来很好。每个用户只存在一次。

在本例中,我将 OpenJPA 1.2 与 IBM DB2 数据库一起使用。

最佳答案

我认为您的模型错误,通常用户角色关系不是 OneToMany 而是“ManyToMany”,因此您应该将代码更改为如下所示:

@Entity
public class MyUser{

 @Id
 @GeneratedValue(strategy = GenerationType.IDENTITY)
 private Long myUserId;

 private String username; 

 @ManyToMany //This should be many to many
 @JoinTable(name = "userrole",
   joinColumns = {
     @JoinColumn(name="myUserId") //The userId in the join table should
                                  //NOT be unique because the userId can
                                  //be many times with different roles
   },
   inverseJoinColumns = {
     @JoinColumn(name="roleId")
   }
 )
 private Collection<Role> roles;    

 public Collection<Role> getRoles() {
     return roles;
 }
}

尝试一下这个方法,看看是否有效。

此外,您的查询不应需要 Left Join,一旦您在每个实体上使用 getRoles() 方法(使用 LAZY Fetch),JPA 应自动获取角色

关于JPA 在列出类的所有实体时返回同一实例的多个对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11886306/

相关文章:

java.lang.illegalstateException无法检索entitymanagerfactory的unitname null

java - @ManyToMany JPA 关系在连接表和 UK 中使用二度关系

java - Java EE 中基于文件的安全数据持久化

java - 如何在 Gridview Android 中保持 CheckBox 持久性(处理复选框状态)?

sql - 如何删除db2中的所有非数字字母

SQL 将行连接到一个字段 (DB​​2)

java - JPA 无交易 Activity

java - JPA - 如何映射两个表之间的关系?

java - 不确定我是否理解 TransactionAwarePersistenceManagerFactoryProxy

SQL语句包含 "IN"子句时的数据库索引