从hibernate查询中获取通用对象

时间:2012-11-16 12:00:23

标签: java generics jpa

http://www.javacodegeeks.com/2012/07/ultimate-jpa-queries-and-tips-list-part_7092.html中所述,您可以从jpa查询中获取对象。 到目前为止,非常好。

但由于我必须经常使用它,我想使用泛型。 而不是

Query query = em.createQuery('select new com.model.PersonDogAmountReport(p, size(p.dogs)) from Person p');

我想要

Query query = em.createQuery('select new com.model.Report<Person, Long>(p, size(p.dogs)) from Person p');

Query query = em.createQuery('select new com.model.Report<com.model.Person, java.lang.Long>(p, size(p.dogs)) from Person p');

。尝试这个给了我以下例外:

org.hibernate.hql.ast.QuerySyntaxException: expecting OPEN, found '<' near line 1

这是否意味着,我想要的只是不受支持? 有没有好的选择?

使用 NamedNativeQuery resultClass 几乎可以做同样的事情,但这样我就不会将Person作为实体。

如果我改为使用object,则无法转换返回的List,这意味着我必须迭代 - &gt; meh desu。

提前感谢您的帮助。

3 个答案:

答案 0 :(得分:4)

无论如何,创建这样的Reports实例是不安全的,因为Hibernate使用反射来实例化和填充报告。所以你可以这样做:

Query query = em.createQuery('select new com.model.Report(p, size(p.dogs)) from Person p');
return (List<Report<Person, Long>>) query.list();

答案 1 :(得分:3)

您需要记住的是,使用Java泛型类型擦除将删除所有泛型类型。这会将List<Person>简化为List<Object>并使用适当的强制转换。在运行时,没有List<Person>这样的东西。所以在这样的情况下,只需获得一个List并自己进行演员表。

答案 2 :(得分:2)

您可能会考虑使用一个简单的子类来绑定泛型类型。所以:

package com.model;

public class PersonLongReport extends Report<Person, Long> {
    public PersonLongReport(Person person, Long long) {
        super(person, long);
    }
}

然后:

public List<? extends Report<Person, Long>> doQuery() {
    TypedQuery<PersonLongReport> query = em.createQuery('select new com.model.PersonLongReport(p, size(p.dogs)) from Person p', PersonLongReport.class);
    return query.getResultList();
}

对于那个简单的子类的成本,你得到类型安全。