过滤延迟初始化的 Hibernate 集合

发布于 2024-09-26 01:02:37 字数 843 浏览 9 评论 0原文

这可能是一个非常简单的答案,因为我确信这并不罕见。我看到一些类似的问题,但似乎没有描述我的问题。

我有两个对象:一辆车和一个人。它们是多对多的关系,即一辆汽车可以由多个人拥有,一个人可以拥有多辆汽车。 Car 有一组延迟初始化的 Drivers

@ManyToMany(targetEntity=Person.class, fetch=FetchType.LAZY)
private Set<Person> people;

我想查找车主年龄在 25 岁以下的所有蓝色汽车:

Criteria foo = persistenceManager.createCriteria(Car.class, "myCarAlias");
Criteria bar = foo.createCriteria("drivers", "myDriverAlias");
//add restrictions on foo and bar for blue and age, respectively
baz = foo.list();

我的问题是当我迭代列表并调用 <在每辆车上调用 code>getDrivers() ,它会初始化集合并获取该车的所有驱动程序。我猜我运行的 .list() 并没有在每辆车上设置结果。

如果我手动运行 Hibernate 生成的 SQL,我会得到预期的结果,因此我有理由确定标准不是问题。

我可以理解为什么会发生这种情况,但我不确定如何在不迭代每辆车并在每辆车上运行驾驶员查询的情况下解决它。如果可能的话,我想避免这样做,并希望得到任何建议。

提前致谢!

This might be a super easy answer, since I'm sure it's not uncommon. I see some similar questions, but nothing that seems to describe my problem.

I have two objects: a car and person. They're in a many-to-many relationship, i.e. a car can be owned by multiple people, and a person can own multiple cars. Car has a lazily initialized set of Drivers:

@ManyToMany(targetEntity=Person.class, fetch=FetchType.LAZY)
private Set<Person> people;

I want to find all blue cars with owners under the age of 25:

Criteria foo = persistenceManager.createCriteria(Car.class, "myCarAlias");
Criteria bar = foo.createCriteria("drivers", "myDriverAlias");
//add restrictions on foo and bar for blue and age, respectively
baz = foo.list();

My problem is when I iterate through the list and call getDrivers() on each car, it initializes the collection and gets all of that car's drivers. I guess the .list() I ran doesn't set the results on each car.

I get back the results I expect if I manually run the SQL hibernate is generating, so I'm reasonably sure the criteria isn't the issue.

I can understand why this happens, but I'm not sure how to get around it without iterating over each car and running a query for drivers on each one. I'd like to avoid doing that if possible and would appreciate any advice.

Thanks in advance!

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

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

发布评论

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

评论(2

君勿笑 2024-10-03 01:02:37

您是否希望每辆车的驾驶员集合仅包含符合您条件的人员(即超过 25 岁)?换句话说,您不希望 Drivers 集合包含 25 岁以上的人员?

如果是这种情况,那么您将需要使用 ResultTransformer (请参阅 Hibernate 文档的第 15.4 节),因为 Hibernate 在返回结果之前不会预先过滤集合。

然而,如果问题是 Drivers 集合被延迟加载,而这是不可取的,那么设置获取模式(我通常使用 JOIN,因为 IIRC FetchMode.EAGER 已被弃用)应该可以解决问题:

baz = persistenceManager.createCriteria(Car.class, "myCarAlias")
    .setFetchMode("drivers", FetchMode.JOIN)
    // add additional restrictions here
    .list();

Were you hoping that the Drivers collection for each Car would only contain People who matched your criteria (i.e. are over 25)? In other words, you don't want the Drivers collection containing people who are over 25?

If that is the case then you will need to use a ResultTransformer (see section 15.4 of the Hibernate documentation) because Hibernate does not pre-filter collections before returning the results.

If however the problem is the Drivers collection is being lazy loaded and that is not desirable then setting the fetch mode (I typically use JOIN since IIRC FetchMode.EAGER was deprecated) should solve the problem:

baz = persistenceManager.createCriteria(Car.class, "myCarAlias")
    .setFetchMode("drivers", FetchMode.JOIN)
    // add additional restrictions here
    .list();
过潦 2024-10-03 01:02:37

Hibernate 文档第 15.5 节。基本上,您可以为条件查询设置获取策略,该策略应优先于您为关系定义的基本获取策略。

文档

List cats = sess.createCriteria(Cat.class)
   .add( Restrictions.like("name", "Fritz%") )
   .setFetchMode("mate", FetchMode.EAGER)
   .setFetchMode("kittens", FetchMode.EAGER)
   .list();

和文档 中的示例
http://docs.jboss.org/hibernate/core /3.3/reference/en/html/querycriteria.html

section 15.5 of the hibernate documentation. Basically you can set the fetch strategy for your criteria queries, which should take precedence over the basic fetch strategy you have defined for the relationship.

the example from the documentation

List cats = sess.createCriteria(Cat.class)
   .add( Restrictions.like("name", "Fritz%") )
   .setFetchMode("mate", FetchMode.EAGER)
   .setFetchMode("kittens", FetchMode.EAGER)
   .list();

and the documentation
http://docs.jboss.org/hibernate/core/3.3/reference/en/html/querycriteria.html

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