JPA TypedQuery错误 [英] JPA TypedQuery error

查看:105
本文介绍了JPA TypedQuery错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我收到错误无法使用请求的结果类型为具有多个返回的查询创建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

I get the error "Cannot create TypedQuery for query with more than one return using requested result type"

for the following query using JPA on Glassfish, any ideas what is wrong here? I want to get the latest debit record with a certain debit status.

 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();

解决方案

A generic parameter is normally specified for a TypedQuery. If you declared a TypedQuery you would use an Object[] as the generic parameter for the TypedQuery, since you are projecting columns and not returning a complete entity.

However, since you have not declared a TypedQuery (your using a concise coding style), you need to change Debit.class to Object[].class since your not selecting an object, but instead only two fields.

 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();

Executing this query will return a Object[] where each index in the Object[] corresponds with a field in your select statement. For example:

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

To avoid using the Object[] you could create a new class to retrieve these values in a more strongly typed fashion. Something like:

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;
    }

}

Then in your JPQL statement you could call the constructor:

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();

Recently, I have blogged about this exact topic. I encourage you to view this video tutorial I created: https://tothought.cloudfoundry.com/post/16

这篇关于JPA TypedQuery错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆