4

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

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

NamedNativeQueryresultClass几乎可以实现同样的事情,但这样我就不会将 Person 作为一个实体。

如果我改用对象,则无法转换返回的列表,这意味着我必须迭代 -> meh desu。

提前感谢您的帮助。

4

3 回答 3

4

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

Query query = em.createQuery('select new com.model.Report(p, size(p.dogs)) from Person p');
return (List<Report<Person, Long>>) query.list();
于 2012-11-16T12:06:17.260 回答
3

您需要记住的是,使用 Java 泛型类型擦除将删除所有泛型类型。这将使用适当的强制转换将 aList<Person>简化为简单的 a 。List<Object>在运行时没有List<Person>. 因此,在这种情况下,只需获得一个List并自己做演员表。

于 2012-11-16T12:07:06.557 回答
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();
}

对于那个微不足道的子类的成本,你得到了类型安全。

于 2012-11-16T13:32:09.813 回答