当前位置: 首页 > 知识库问答 >
问题:

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

嵇浩然
2023-03-14

我有一个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;
 }
}

如果是入侵,角色实体非常简单。

@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数据库。

共有2个答案

华旭
2023-03-14

实际上,让@ManyToMany映射用户和用户角色实体是合理的。您的查询的问题是它返回了连接表中的所有行,我相信您并不需要这些行。因此,只需将< code>group by u添加到查询中,如下所示:

SELECT u FROM MyUser u LEFT JOIN FETCH u.roles GROUP BY u

你就完事了。

元鸿波
2023-03-14

我认为你的模型是错误的,典型的用户角色关系不是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;
 }
}

试试这种方法,看看是否有效。

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

 类似资料:
  • 问题内容: 我正在写一个跨三个表的JPQL查询。在我的结果列表中,我想获得每个匹配行的所有三个实体(希望如此)。 有任何想法吗? Hibernate 3.x是我的JPA提供程序。 问题答案: IIRC,您可以执行,结果将是,其中数组内容将包含o1,o2,o3值。

  • 问题内容: 在Java中,是否有任何可能的方法来获取某个类的所有实例? 问题答案: 实例化类(Singleton模式)时,可以使用Factory静态初始化程序,然后将工厂构造函数中的每个生成的实例添加到List中。 像这样的东西:

  • 我没有问题绑定单例实例到其他一些实例使用@注入。但是,当涉及到绑定一个类的更多实例到其他一些实例(这是单例),它拒绝以某种方式绑定它,我得到了空引用。 我的代码示例是: 当我创建几个WebSocketManagerImpl实例时,每个factoryImpl字段都是空指针。我做错什么了吗?

  • 当我映射同一个实体时,就像这里回答的那样: Hibernate与同一实体的多对多关联 在“tbl_friends”表中,我有相同含义的行。例如,我有id=1的用户和id=2的用户。在“tbl_friends”表中,当他们作为朋友链接时,我有两行 使用Hibernate或JPA引用是否可以在一行(1-2或2-1)中建立这种关系?

  • 有人能解释一下下面的代码是如何毫无例外地工作的吗。我在想,当为星期天创建新实例时,它也会为星期一(星期天内)创建一个新实例,然后再为星期天(星期一内)创建一个新实例,以此类推。。。类似递归的东西,因为它们都是课程周的一部分。但我的理解是错误的,因为下面的代码运行良好。 我有这个疑问,当我读到java枚举。

  • 场景: 我正在使用独立设置测试Spring MVC控制器。 控制器从请求中的JSON对象获取参数。它在将JSON对象转换成java对象后调用一个服务。该服务使用JPA将其保存到DB,然后更新实体的Id字段并返回给控制器。在将实体转换成JSON之后,控制器将JSON响应返回给调用者。 我已经在我的测试类中模拟了该服务,并使用@InjectMocks注入到控制器中 模拟服务无法访问JPA实体的私有se