使用 OneToMany 属性上的过滤器查询实体会给出奇怪的结果
我使用 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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
您的查询仅返回人员。获取人员后,您将调用 getAddresses(),它会延迟加载人员的地址 - 所有地址。简而言之,查询限制了返回的人员集合,但由于它仅返回人员,因此在访问地址集合时使用另一个查询来延迟加载地址。
您想要做的是在单个查询中返回人员及其部分地址。为此,您需要使用
fetch
关键字:但是要非常小心:此查询返回人员实体的错误视图。您应该确保不要修改返回人员的地址集合(尽管由于地址关联是由
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: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).