Hibernate多对多实体属性的标准化查询条件

3
@Entity
class A {

@ManyToMany
private List<B> list;
...
}

@Entity
class B {
...
}

我希望使用条件(而不是SQL查询)从A类中获取列表。这可行吗?在这种情况下,投影无法使用。

2个回答

4

不幸的是,准则只允许选择根实体,而不是任何加入的实体。因此,如果您的ManyToMany是双向的,那么就会更容易。您可以使用等效于准则的方法来实现:

select b from B b inner join b.as a where a = :theA

如果这不是一个选项,我认为唯一的方法就是使用子查询,从而编写等效于以下条件的代码。
select b from B b where b.id in (select b2.id from A a inner join a.list b2 where a.id = :theAId)

代码应该是这样的:
Criteria c = session.createCriteria(B.class, "b");

DetachedCriteria dc = DetachedCriteria.forClass(A.class, "a");
dc.createAlias("a.list", "b2");
dc.add(Restrictions.eq("a.id", theA.getId()));
dc.setProjection(Projections.property("b2.id"));

c.add(Subqueries.propertyIn("b.id", dc));

还要注意,IN语句有时会受到SGDB的限制(例如我认为在Oracle中我们只能在IN语句中放置1000个值)。也许你最好运行一个单独的查询来获取列表,然后将其拆分成子列表(使用Guava分区函数?),并对所有子列表运行子查询。 - Sebastien Lorber
在这种情况下,IN语句使用子查询而不是文字值列表。在此情况下,由子查询返回的项目数量没有任何限制。 - JB Nizet

-1

假设a是A类的实例,你应该能够调用它。

a.getList();

如果A类已经设置了适当的getter和setter,我不认为需要使用Criteria查询。

1
并不是因为你可以使用对象来完成某些操作,就意味着使用SQL/HQL/Criteria查询不能够有用,例如出于性能方面的考虑... - Sebastien Lorber

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接