【问题标题】:create hibernate query to perform sum of two select query columns创建休眠查询以执行两个选择查询列的总和
【发布时间】:2019-12-10 04:54:30
【问题描述】:

我有两个 select 语句,每个语句计算一列的总和。需要获取两个 select 语句的总和。它在普通 sql 中工作,但不适用于休眠的 @Query 注释。

尝试使用正常的 sql 查询运行上述问题,但同样不适用于休眠 @Query 注释


select sum((SELECT   SUM(TRAN_AMT+FEE_AMT)
            FROM pymt 
            WHERE TRANTM between '2019-06-01 00:00:00' and  '2019-06-23 23:59:59'
            AND PAYEE = unhex('xxxxxx')
            AND TRANTYPECDE = '003' 
            AND RESP_CDE = 'Success')-(

SELECT   SUM(TRAN_AMT-FEE_AMT)
            FROM pymt
            WHERE TRAN_CAPTR_DT_TM between '2019-06-01 00:00:00' and  '2019-06-23 23:59:59'
            AND PAYEE = unhex('xxxxxx')
            AND TRANTYPECDE != '003' 
            AND RESP_CDE = 'Success')) as sumValue;   

上面的工作正常,但下面的查询在休眠状态下不工作

    @Query(value = "SELECT SUM((SELECT   SUM(p.feeAmt + p.tranAmt) "
                    +"FROM PymtEntity p " 
                    + "WHERE p.tranCaptrTm >= :from AND p.tranCaptrTm <= :to "
                    +"AND p.tranTypeCde = '003' " 
                    + "AND p.payeeId = :md "
                    + "AND p.respCde = :re )"
                    +"-"
                    +"(SELECT   SUM( p.tranAmt - p.feeAmt) "
                    +"FROM PymtEntity p " 
                    + "WHERE p.tranCaptrTm >= :from AND p.tranCaptrTm <= :to "
                    +"AND p.tranTypeCde != '003' " 
                    + "AND p.payeeId = :md "
                    + "AND p.respCde = :re )) as sumtotal")

上面返回QuerySyntaxException:子树的意外结束

预计要打印的总和 但得到 QuerySyntaxException: 休眠中子树的意外结束

堆栈跟踪

    ... 29 common frames omitted
Caused by: java.lang.IllegalArgumentException: org.hibernate.hql.internal.ast.QuerySyntaxException: unexpected end of subtree [SELECT SUM((SELECT   SUM(p.feeAmt + p.tranAmt) FROM com.hsbc.digital.peak.payments.reporting.data.entities.PymtEntity  p WHERE p.tranCaptrTm >= :from AND p.tranCaptrTm <= :to AND p.tranTypeCde = '003' AND p.payeeId = :merchantId AND p.respCde = :respCode )-(SELECT   SUM( p.tranAmt - p.feeAmt) FROM com.hsbc.digital.peak.payments.reporting.data.entities.PymtEntity  p WHERE p.tranCaptrTm >= :from AND p.tranCaptrTm <= :to AND p.tranTypeCde != '003' AND p.payeeId = :merchantId AND p.respCde = :respCode )) as sumtotal]
    at org.hibernate.internal.ExceptionConverterImpl.convert(ExceptionConverterImpl.java:138)
    at org.hibernate.internal.ExceptionConverterImpl.convert(ExceptionConverterImpl.java:181)
    at org.hibernate.internal.ExceptionConverterImpl.convert(ExceptionConverterImpl.java:188)
    at org.hibernate.internal.AbstractSharedSessionContract.createQuery(AbstractSharedSessionContract.java:713)
    at org.hibernate.internal.AbstractSessionImpl.createQuery(AbstractSessionImpl.java:23)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.springframework.orm.jpa.ExtendedEntityManagerCreator$ExtendedEntityManagerInvocationHandler.invoke(ExtendedEntityManagerCreator.java:350)
    at com.sun.proxy.$Proxy135.createQuery(Unknown Source)
    at org.springframework.data.jpa.repository.query.SimpleJpaQuery.validateQuery(SimpleJpaQuery.java:87)
    ... 58 common frames omitted
Caused by: org.hibernate.hql.internal.ast.QuerySyntaxException: unexpected end of subtree [SELECT SUM((SELECT   SUM(p.feeAmt + p.tranAmt) FROM com.hsbc.digital.peak.payments.reporting.data.entities.PymtEntity  p WHERE p.tranCaptrTm >= :from AND p.tranCaptrTm <= :to AND p.tranTypeCde = '003' AND p.payeeId = :merchantId AND p.respCde = :respCode )-(SELECT   SUM( p.tranAmt - p.feeAmt) FROM com.hsbc.digital.peak.payments.reporting.data.entities.PymtEntity  p WHERE p.tranCaptrTm >= :from AND p.tranCaptrTm <= :to AND p.tranTypeCde != '003' AND p.payeeId = :merchantId AND p.respCde = :respCode )) as sumtotal]
    at org.hibernate.hql.internal.ast.QuerySyntaxException.convert(QuerySyntaxException.java:74)
    at org.hibernate.hql.internal.ast.ErrorTracker.throwQueryException(ErrorTracker.java:93)
    at org.hibernate.hql.internal.ast.QueryTranslatorImpl.analyze(QueryTranslatorImpl.java:277)
    at org.hibernate.hql.internal.ast.QueryTranslatorImpl.doCompile(QueryTranslatorImpl.java:191)
    at org.hibernate.hql.internal.ast.QueryTranslatorImpl.compile(QueryTranslatorImpl.java:143)
    at org.hibernate.engine.query.spi.HQLQueryPlan.<init>(HQLQueryPlan.java:119)
    at org.hibernate.engine.query.spi.HQLQueryPlan.<init>(HQLQueryPlan.java:80)
    at org.hibernate.engine.query.spi.QueryPlanCache.getHQLQueryPlan(QueryPlanCache.java:153)
    at org.hibernate.internal.AbstractSharedSessionContract.getQueryPlan(AbstractSharedSessionContract.java:595)
    at org.hibernate.internal.AbstractSharedSessionContract.createQuery(AbstractSharedSessionContract.java:704)
    ... 66 common frames omitted

【问题讨论】:

  • 你为什么不在没有所有子查询的情况下对总和进行一次查询?我坚信这是可能的
  • 因为我有不同的条件,我需要进行两个选择查询。事情是一个选择查询@Query注释正在工作
  • 对于您发布的查询,它是完全相同的查询的 2 倍。看起来您在第二个AND p.payeeId = :md 中缺少!。同时发布整个堆栈跟踪
  • 编辑相同

标签: java mysql hibernate


【解决方案1】:

自从我开发它以来我就有偏见,但是这可以通过FluentJPA 解决,因为它将本机 SQL 提供给 Hibernate:

@Entity
@Data // lombok
public static class PymtEntity {
    @Id
    private int id;
    private int feeAmt;
    private int tranAmt;
    private Timestamp tranCaptrTm;
    private String tranTypeCde;
    private int payeeId;
    private String respCde;
}

public int sumTwoColumns(Date from,
                         Date to,
                         int md,
                         String re) {
    FluentQuery query = FluentJPA.SQL(() -> {
        PymtEntity common = subQuery((PymtEntity pymt) -> {
            SELECT(pymt);
            FROM(pymt);
            WHERE(BETWEEN(pymt.getTranCaptrTm(), from, to) && pymt.getPayeeId() == md
                                                           && pymt.getRespCde() == re);
        });

        PymtEntity first = subQuery(() -> {
            SELECT(common);
            FROM(common);
            WHERE(common.getTranTypeCde() == "003");
        });

        PymtEntity second = subQuery(() -> {
            SELECT(common);
            FROM(common);
            WHERE(common.getTranTypeCde() != "003");
        });

        SELECT(SUM(pick(first, SUM(first.getFeeAmt() + first.getTranAmt()))
                - pick(second, SUM(second.getTranAmt() - second.getFeeAmt()))));
    });

    return query.createQuery(em, Integer.class).getSingleResult();
}

而生成的SQL是:

SELECT SUM(((SELECT SUM((q3.fee_amt + q3.tran_amt)) 
FROM (SELECT q2.* 
FROM (SELECT t0.* 
FROM PymtEntity t0 
WHERE ((t0.tran_captr_tm BETWEEN ?1 AND ?2 ) AND ((t0.payee_id = ?3) AND (t0.resp_cde = ?4))) ) q2 
WHERE (q2.tran_type_cde = '003') ) q3 ) - (SELECT SUM((q4.tran_amt - q4.fee_amt)) 
FROM (SELECT q2.* 
FROM (SELECT t0.* 
FROM PymtEntity t0 
WHERE ((t0.tran_captr_tm BETWEEN ?1 AND ?2 ) AND ((t0.payee_id = ?3) AND (t0.resp_cde = ?4))) ) q2 
WHERE (q2.tran_type_cde <> '003') ) q4 )))

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-05-19
    • 1970-01-01
    • 1970-01-01
    • 2012-01-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多