我收到错误“无法使用请求的结果类型为具有多个返回的查询创建TypedQuery”

对于以下在Glassfish上使用JPA的查询,您有什么想法吗?我想获取具有特定借记状态的最新借记记录。

 entityManager.createQuery("select dd, MAX(dd.createdMillis) from T_DEBIT dd" +
                " where dd.debitStatus in (:debitStatus)" +
                " and dd.account = :account" , Debit.class)
                .setParameter("debitStatus", false)
                .setParameter("account", account)
                .getSingleResult();

最佳答案

通常为TypedQuery指定通用参数。如果声明了TypedQuery,则将Object[]用作TypedQuery的通用参数,因为您要投影列而不返回完整的实体。

但是,由于尚未声明TypedQuery(使用简洁的编码样式),因此您需要将Debit.class更改为Object[].class,因为您没有选择对象,而是仅选择了两个字段。

 Object[] result = entityManager.createQuery("select dd, MAX(dd.createdMillis) from T_DEBIT dd" +
                " where dd.debitStatus in (:debitStatus)" +
                " and dd.account = :account" , Object[].class) //Notice change
                .setParameter("debitStatus", false)
                .setParameter("account", account)
                .getSingleResult();


执行此查询将返回一个Object[],其中Object[]中的每个索引对应于select语句中的一个字段。例如:

result[0] = dd
result[1] = max(dd.createdMillis)


为了避免使用Object[],您可以创建一个新类以更强类型的方式检索这些值。就像是:

public class Result {

    String dd;
    Date createdMillis;

    public Result(String dd, Date createdMillis) {
        super();
        this.dd = dd;
        this.createdMillis = createdMillis;
    }

    public String getDd() {
        return dd;
    }

    public void setDd(String dd) {
        this.dd = dd;
    }

    public Date getCreatedMillis() {
        return createdMillis;
    }

    public void setCreatedMillis(Date createdMillis) {
        this.createdMillis = createdMillis;
    }

}


然后,在您的JPQL语句中,您可以调用构造函数:

Result result = entityManager.createQuery("select NEW fully.qualified.Result(dd, MAX(dd.createdMillis)) from T_DEBIT dd" +
                " where dd.debitStatus in (:debitStatus)" +
                " and dd.account = :account" , Result.class)
                .setParameter("debitStatus", false)
                .setParameter("account", account)
                .getSingleResult();


最近,我在博客上发表了这个确切的话题。我鼓励您观看我创建的该视频教程:https://tothought.cloudfoundry.com/post/16

07-25 20:38