2012-04-02 89 views
4

我观察的读取与条件查询列表属性时,我认为是在JPA 2意外的行为。JPA标准中获取列表查询重复值

我的查询如下(它的提取物):

CriteriaBuilder b = em.getCriteriaBuilder(); 
CriteriaQuery<MainObject> c = b.createQuery(MainObject.class); 
Root<MainObject> root = c.from(MainObject.class); 
Join<MainObject, FirstFetch> firstFetch = (Join<MainObject, FirstFetch>) root.fetch(MainObject_.firstFetch); 
firstFetch.fetch(FirstFetch_.secondFetch); //secondFetch is a list 
c.select(root).distinct(true); 

(所以我们可以说,我取一个列表作为一个对象的属性的属性。)

事情是当查询返回多个结果时,secondFetch值会重复多次以返回行。每个firstFetch应该只有一个secondFetchñ代替。 我在这种情况下看到的唯一特别之处在于所有MainObjects碰巧有相同FirstFetch实例。 所以我的猜测是连接正在越过,这是正常的,但随后JPA未能将secondFetch对象分配给每个firstFetchs

映射应该不会太特别,the're或多或少这样

@Entity 
@Table(name="mainobject") 
public class MainObject{ 
    //... 
    private FirstFetch firstFetch; 

    @ManyToOne(fetch=FetchType.LAZY) 
    @JoinColumn(name="mainObject_column") 
    public FirstFetch getFirstFetch() { 
    return firstFetch; 
    } 
} 

@Entity 
@Table(name="firstFetch") 
public class FirstFetch{ 
    //... 
    private List<SecondFetch> secondFetch; 

    @OneToMany(mappedBy="secondFetch") 
    public List<SecondFetch> getSecondFetch() { 
     return secondFetch; 
    } 
} 

&终于

@Entity 
@Table(name="secondFetch") 
public class SecondFetch { 
    //.... 
    private FirstFetch firstFetch; //bidirectional 

    @ManyToOne 
    @JoinColumn(name="column") 
    public FirstFetch getFirstFetch() { 
     return firstFetch; 
    } 
} 

我一直在寻找某种截然不同的句子适用到取,但有没有(本来是一个“补丁”反正...)

如果我改变

List<SecondFetch> 

Set<SecondFetch> 

我会得到预期的结果归功于套',所以我确实觉得这是JPA列表中的一种不当行为。

我不是专家,不过,所以我可以perfectlly可以使得在映射或查询的一些错误。 任何反馈都非常欢迎帮助清除此问题。 谢谢。

+0

您使用的是JPA提供程序?可能是一个错误。 – James 2012-04-03 14:22:28

+0

我正在使用JBoss 6.1.0的默认提供程序,如果我没有错,这将是Hibernate 3.6.6 Final。 – 2012-04-05 13:21:04

+0

我有完全相同的问题。 我使用标准api来获取像这样的(第二个)列表: d.fetch(FirstFetch_.secondFetch,JoinType.LEFT); – Jens 2012-04-19 07:50:27

回答

3

我有完全相同的问题,但我使用JPA标准API做查询。

经过一番研究,我发现,你已经提到的(但不可用,因为你没有使用标准的API)的解决方案:使用distinct

使用JPA标准,它应该是这样的:

CriteriaQuery<FirstFetch> query = cb.createQuery(FirstFetch.class); 
Root<AbschnittC> root = query.from(FirstFetch.class); 
root.fetch(FirstFetch_.secondFetch, JoinType.LEFT); 
query.distinct(true); 

不使用query.distinct(true);结果集与对象在secondFetch列表中的量成倍增加。

休眠确实有像DISTINCT_ROOT_ENTITY这听起来比只是设置一个查询不同。但我没有进一步调查这一点。我也使用Hibernate作为JPA提供者。也许在JPA中设置query截然不同,它使用与Hibernates DISTINCT_ROOT_ENTITY相同的代码?

+0

感谢您的反馈,我会看看这个DISTINCT_ROOT_ENTITY并尽快更新 – 2012-04-23 21:52:03

+0

您的示例只能执行一次fetch();我不认为它和上面描述的一样。 – rakslice 2014-07-16 18:36:38