具有内部列表条件的休眠 NamedQuery

Posted

技术标签:

【中文标题】具有内部列表条件的休眠 NamedQuery【英文标题】:Hibernate NamedQuery with a condition on inner List 【发布时间】:2012-09-14 11:46:32 【问题描述】:
    class A
// one to many mapping
    List<B> listOfB;
    //getter and setter;
    class B 
    String s;
    //getter and setter
    

现在,当我得到类 A 时,它将返回 listOfB 中所有关联的类 B。但我需要确定 B 中的哪一个应该做出回应。像 Get A 这样 listOfB 包含所有这样的 B s = 'something'。

编辑:目前这不起作用:

select a from A a where a.listOfB IN (select b from a.listOfB b where b.s='something');

【问题讨论】:

【参考方案1】:

1) 我假设您映射了从 A 到 B 的一对多关系,例如 A.listOfB = B.b

我认为您的查询可以简化为:

select a 
from A a, B b
where a.listOfB = b.b
and where b.s='something'

等效的 Hibernate Criteria 查询将是:

List results =  sess.createCriteria(A.class)  
    .createCriteria("listOfB")
    .add(Restrictions.eq("s", "something"))
    .list();

2) 如果这些实体之间没有映射关系,您可以在字段 a.listOfB 上使用 SQLRestriction

List results = sess.createCriteria(A.class)
.add( Restrictions.sqlRestriction("alias.listOfB in (selec b from B where b.s = ?)), "something", Hibernate.STRING) )
   .list();

更多示例here。

【讨论】:

您的 HQL 查询无效:b.b 不存在,无法将列表与实体进行比较。此外,这不会解决 OP 的问题:他仍然会获得每个 A 中 B 的完整列表,而不仅仅是满足标准的 B。【参考方案2】:

你可以用 Hibernate 做到这一点,尽管 JPA 规范说它应该被禁止。事实上,当你得到一个A 时,它的 B 列表应该始终是完整的列表 a B。不是已被某些查询过滤的列表。我会避免这样做,因为它很危险。相反,我会使用如下查询:

select a, b from A a inner join a.listOfB b where b.s = 'something'

现在你已经拥有了所有你感兴趣的 As 和所有你感兴趣的 B:

A1, B1
A1, B2
A2, B7
A2, B8

如果您真的想获得带有部分 B 列表的 As,请使用以下查询。但是你已经被警告了:它不便携,而且很危险:

select a from A a inner join fetch a.listOfB b where b.s = 'something'

【讨论】:

以上是关于具有内部列表条件的休眠 NamedQuery的主要内容,如果未能解决你的问题,请参考以下文章

使用 NamedQuery 进行内部联接?

过滤具有内部列表条件的列表

来自标准查询的休眠 NamedQuery --> 需要帮助

具有 INNER JOIN 条件的 JPA 命名查询失败

具有嵌入对象的实体的休眠条件

使用具有多个条件的内部联接