使用OneToMany属性上的过滤器查询实体会产生奇怪的结果

时间:2011-12-06 19:24:27

标签: java jpa eclipselink jpql

我使用EclipseLink 9个月,到目前为止没问题。因为我有 需要使用OneToMany属性查询实体,情况恰恰相反。 它给了我一个奇怪的结果。 我已将我的实体简化为最大值,但问题仍然存在。

我将解释我的需求,这非常简单:我有两个实体: 与地址具有双向关系的人。 人有可能有几个地址,但地址属于一个和 只有人。

在Classes中,它给出了:

@Entity
public class Person implements Serializable {

    @Id
    private Long id;

    @OneToMany(mappedBy = "person", fetch = FetchType.LAZY)
    private Set<Address> addresses;

    // Getter and setter
      ...
}


@Entity
public class Address implements Serializable {

    @Id
    private String idAddress;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "idPerson", referencedColumnName = "idPerson")
    private Person person;

    // Getter and setter
    ...
}

我想用他们的地址查询personne。所有这些都有一些条件 在personne和adresse上。 我的简化查询:

select pers FROM Person pers join pers.addresses address
                 where pers.matricule=:matricule                    
                 and address.date=:dateContract

当我执行它时,我会检索合适的人,但所有地址都是 与此人联系(与外键)。即使是没有的地址 与dateContract条件匹配。

这似乎与在oneToMany上使用过滤相关的问题 我的查询中的属性。如果我做了几个请求,问题就解决了 它会提供低性能,因为我有这样的几个要求。 我已经尝试使用oneToMany进行急切初始化并使用 fetch-join查询提示,但我得到了相同的结果。

感谢您阅读我:)

PS:我手动编写了代码,所以有点错字

大卫

1 个答案:

答案 0 :(得分:1)

您的查询仅返回人员。一旦你找到了这些人,你就会调用getAddresses(),它懒洋洋地加载了这个人的地址 - 所有这些。简而言之,查询限制了返回人员的集合,但由于它只返回人员,因此在访问地址集时,使用其他查询延迟地址加载地址。

您要做的是在一个查询中将具有某些地址的人员退回。为此,您需要使用fetch关键字:

select distinct pers FROM Person pers 
join fetch pers.addresses address
where pers.matricule = :matricule                    
and address.date = :dateContract

但要非常小心:此查询返回人员实体的错误视图。您应该确保不修改返回人员的地址集合(尽管由于地址关联由Address.person关联映射而且没有级联,因此在这种特殊情况下您不应该遇到问题。)