使用 Criteria 和获取类型 eager 时出现问题
我有两个实体:用户和地址。用户有一个“地址”属性:
@OneToMany (mappedBy="user", fetch=FetchType.EAGER)
public List<Adress> getAddress() {
return this.address;
}
public void setAddress(List<Adress> address) {
this.address= address;
}
获取类型是急切的,如上所示。
我正在尝试使用 Criteria 来获取用户列表,如下所示:
List<User> p=session.createCriteria(User.class).list();
不幸的是,如果用户有多个地址,它会重复用户。关闭急切获取后,它不会获得重复项。如何使用 Criteria 获取没有重复项目的用户列表?
I have two entities: User and Address. User has an "address" property:
@OneToMany (mappedBy="user", fetch=FetchType.EAGER)
public List<Adress> getAddress() {
return this.address;
}
public void setAddress(List<Adress> address) {
this.address= address;
}
The fetch type is eager as shown above.
I'm trying to use Criteria in order to get a list of Users as follows:
List<User> p=session.createCriteria(User.class).list();
Unfortunately it gets repeated users if a user has more than one address. With eager fetching turned off, it doesn't get duplicates. How can I get a list of users without repeated items using Criteria?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
不鼓励将*对多关系映射为 FetchType.EAGER。如果您需要急切获取,则可以在每个查询的基础上进行操作。话虽这么说,当您使用 FetchType.EAGER 时,Hibernate 切换到外部连接选择,因为这对于急切获取确实相关的情况最有意义。当然,外部联接会导致您所看到的行为。我建议您删除 FetchType.EAGER 并编写适当的查询来获取您想要的数据。
不太推荐的替代方案是将
@Fetch(FetchMode.SELECT)
添加到您的映射中。这意味着每次加载用户时,它都会发出两个选择:一个用于用户,一个用于地址。无论如何,这本质上与您使用惰性关系相同,那么有什么意义呢?It's discouraged to map *-to-many relationships as FetchType.EAGER. If you need eager fetching, you do it on a per-query basis. That being said, when you use FetchType.EAGER, Hibernate switches to an outer join select, as that's what makes the most sense for situations where eager fetching is really relevant. An outer join, of course, causes the behavior you're seeing. I'd recommend you remove the FetchType.EAGER and write an appropriate query to fetch the data you want.
The less-recommended alternative would be to add
@Fetch(FetchMode.SELECT)
to your mapping. This means every time you load a user, it will issue two selects: one for the user and one for the addresses. This is essentially the same as if you were using a lazy relationship anyway, so what's the point?设置
mycrit.setFetchMode("address", FetchMode.SELECT)
。然后它会为关联运行单独的选择,您不会被欺骗。Set
mycrit.setFetchMode("address", FetchMode.SELECT)
. Then it runs a separate select for the association and you won't get dupes.