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

发布于 2024-12-19 15:07:56 字数 1258 浏览 0 评论 0原文

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

我将解释我的需求,这是非常简单的:我有两个实体: 与地址有双向关系的人员。 一个人可能有多个地址,但一个地址属于一个,并且 唯一的人。

在类中,它给出:

@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
    ...
}

我想查询人员及其地址。所有这一切都需要一定的条件 关于人员和地址。 我的简化查询:

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

当我执行它时,我检索到正确的人但包含所有地址 与此人链接(使用外键)。即使没有的地址 与 dateContract 条件匹配。

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

感谢您阅读我的文章:)

PS:我手动编写了代码,所以一点错字也不是不可能的

David

I use EclipseLink for 9 months and so far no problem. Since I have the
need to query an entity with a OneToMany attribute, it's all the contrary.
It gives me a strange result.
I have simplified my entities until the maximum but the problem remains.

I will explain my need which is ultra simple : I have two entities :
Person which has a bidirectional relation with Address.
Person has potentially several Addresses but an Address belongs to one and
only Person.

In Classes, it gives that :

@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
    ...
}

I want to query personne with their adresses. All that with some conditions
on personne and adresse.
My simplified query :

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

When I execute it, I retrieve the right person but with all addresses
linked (with foreign key) with this person. Even the addresses which don't
match with the dateContract condition.

It seems that it's a problem related to the use of filtering on a oneToMany
attribute in my query. The problem is solved if i do several requests but
it will give low performances as I have several requests like this.
I have tried with the oneToMany in eager initialization and with a
fetch-join query hint but i have got the same result.

Thank you for having read me :)

PS : I have written the code manually, so a little typo is not impossible

David

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

拒绝两难 2024-12-26 15:07:56

您的查询仅返回人员。获取人员后,您将调用 getAddresses(),它会延迟加载人员的地址 - 所有地址。简而言之,查询限制了返回的人员集合,但由于它仅返回人员,因此在访问地址集合时使用另一个查询来延迟加载地址。

您想要做的是在单个查询中返回人员及其部分地址。为此,您需要使用 fetch 关键字:

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

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

Your query only returns persons. Once you get the persons, you're calling getAddresses(), which lazily loads the addresses of the person - all of them. In short, the query limits the set of returned persons, but since it only returns persons, the addresses are lazy-loaded using another query when accessing the set of addresses.

What you want to do is return the persons with some of their addresses in a single query. To do that, you need to use the fetch keyword:

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

Be very careful, though: this query returns an incorrect view of the person entity. You should make sure not to modify the collection of addresses of the returned persons (although since the addresses association is mapped by the Address.person association and there is no cascade, you should not have problems in this particular case).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文