如何构建一个使用集合中所有元素的单个元素的hibernate查询?

时间:2009-06-12 18:12:25

标签: hibernate collections

情况如下:

我有一个数据类型C,它具有对数据类型P的一对多引用。 数据类型P有一个可选的R引用(一对一)。

我尝试的查询如下(它是一个计数,但它也将用于提取数据)

FROM C WHERE ... AND P.R.rProperty LIKE 'BLAH%';

我得到了

org.hibernate.QueryException: illegal attempt to dereference collection 
[C.C_SEQUENCE_NUMBER.P] with element property reference [R] [select count(*) FROM C a WHERE a.DATE_FIELD >= ? AND a.DATE_FIELD <= ? AND a.P.R.rProperty LIKE ?]

任何提示/建议?

4 个答案:

答案 0 :(得分:1)

尝试以下

"FROM EntityC c inner join EntityP p WHERE p.R.rProperty LIKE 'BLAH%'"

答案 1 :(得分:1)

我知道这对你来说太迟了,但它可能对其他人有所帮助。据我所知,你不能引用“子属性”。在某种程度上,这是LOD (Law Of Demeter)的表现,这实际上意味着你只能使用一个点。尽管在这个类层次结构中并非如此,但是nhibernate希望您在hql中引用对象/属性。所以你可以这样写:

from C c 
inner join fetch P p 
inner join fetch R r
where r.rProperty like 'BLAH%';

fetch用来告诉hibernate / nhibernate急切加载实体以避免SELECT N + 1问题。我猜你想在这种情况下预加载所有实体。

答案 2 :(得分:0)

我在这里错过了什么或者应该是

FROM C c WHERE ... AND c.p.r LIKE 'BLAH%';

嗯,让我们正确地重写

Class Foo {
   public List<Bars>getBars();
}

class Bar {
   public Baz getBaz();
}

Foo是你的C,Bar是你的P,Baz是你的R. 然后你的hql就像

from Foo f where f.bars.baz like 'BLAHH' 

答案 3 :(得分:0)

你可以从实体P开始,只要它有一个包含实体C的“反向链接”,即所谓的双向映射。

您可以通过使用ResultTransformer指定select或Criteria来使用HQL实现此目的。

e.g。

select p.C from P p where p.r.property like 'BLAH%';

s.createCriteria(P.class)
 .createAlias("c","toSelect")
 .createCriteria("r")
 .add(Restrictions.like("property","BLAH%")
 .setResultTransformer(new ResultTransformer() {
      public Object transformTuple(Object[] tuple, String[] aliases) {
        for (int i = 0; i < aliases.length; i++) {
          if ("toSelect").equals(aliases[i])) {
            return tuple[i];
          }
        }
        throw new RuntimeException("What?");
      }
     ...
   })
 .list();