2012-08-09 42 views
1

我有一個很奇怪的問題。當列出一個類的所有實體時,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數據庫。

有沒有人看過類似的問題?

回答

1

我覺得你有你的模型錯了,通常是用戶角色關係不是一對多,但「多對多」,所以你應該改變你的代碼看起來是這樣的:

@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獲取)

+0

謝謝。 @ManyToMany是正確的,是的。增加了@ManyToMany(casscade = CascadeType.ALL,fetch = FetchType.EAGER),並解決了這個問題。 – 2012-08-13 13:37:55

+0

太棒了!我很高興爲你工作! – 2012-08-14 02:14:05

1

其實,這是合理的做法是取@用戶和UserRole實體的ManyToMany映射。你的查詢的問題是,它返回連接表中的所有行,我相信你不需要。所以只需添加group by u到您的查詢,如下所示:

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

,你會做。

相關問題