如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。
提前感谢您的帮助。
答案 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();
}
对于那个简单的子类的成本,你得到类型安全。