当列出一个类的所有实体时,JPA返回同一实例的多个对象
问题描述:
我有一个很奇怪的问题。当列出一个类的所有实体时,JPA返回同一实例的多个对象
我有一个具有子实体列表的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;
}
}
如果intressting,角色的实体是非常简单的。
@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数据库。
有没有人看过类似的问题?
答
我觉得你有你的模型错了,通常是用户角色关系不是一对多,但“多对多”,所以你应该改变你的代码看起来是这样的:
@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;
}
}
试试这个方法,看看是否有用。
而且您的查询应该不需要左加入,角色应自动JPA一旦你使用getRoles()方法对每个实体(使用LAZY获取)
答
其实,这是合理的做法是取@用户和UserRole实体的ManyToMany映射。你的查询的问题是,它返回连接表中的所有行,我相信你不需要。所以只需添加group by u
到您的查询,如下所示:
SELECT u FROM MyUser u LEFT JOIN FETCH u.roles GROUP BY u
,你会做。
谢谢。 @ManyToMany是正确的,是的。增加了@ManyToMany(casscade = CascadeType.ALL,fetch = FetchType.EAGER),并解决了这个问题。 – 2012-08-13 13:37:55
太棒了!我很高兴为你工作! – 2012-08-14 02:14:05