为什么JPQL生成的查询与原始查询不同

时间:2015-07-27 10:35:55

标签: java sql eclipselink spring-roo entitymanager

我正在审查这样的JPQL查询:

SELECT   SELECT   SUM(  func('NVL', l.prim_emiti_ced_periodo, 0) 
    + func('NVL', l.prim_dev_n_emiti_ced_fin, 0) 
    - func('NVL', l.prim_dev_n_emiti_ced_ini, 0)) 
    primas_cedidas_netas, 
    SUM(  func('NVL', l.com_prim_emiti_ced_periodo, 0) 
    + func('NVL', l.com_prim_dev_n_emiti_ced_fin, 0) 
    - func('NVL', l.com_prim_dev_n_emiti_ced_ini, 0)) 
    gastos_reintegrados, 
    SUM (func('NVL', l.reaj_com_segun_siniestralidad, 0)) 
    reajustes_gastos_reintegrados, 
    SUM (func('NVL', l.prest_gastos_pagados_ced, 0)) siniestros_pagados, 
    SUM (func('NVL', l.recobros_cedidos, 0)) siniestros_recobrados, 
    SUM (func('NVL', l.deposito_sobre_prim_fin, 0)) deposito_retenido_a_X, 
    SUM (func('NVL', l.deposito_sobre_prim_ini, 0)) deposito_reembolsado, 
    SUM(func('NVL', l.prim_dev_n_emiti_ced_fin, 0) 
    + func('NVL', l.prim_emiti_ced_pend_cob_fin, 0)) 
    primas_pend_cobro_a_X, 
    SUM (func('NVL', l.detrac_sobre_deposito_prim_fin, 0)) 
    detraccion_depo_retenido, 
    SUM(func('NVL', l.com_prim_dev_n_emiti_ced_fin, 0) 
    + func('NVL', l.com_prim_emit_ce_pedte_cob_fin, 0)) 
    gasto_reinteg_s_pp, 
    SUM(func('NVL', l.prim_dev_n_emiti_ced_ini, 0) 
    + func('NVL', l.prim_emiti_ced_pend_cob_ini, 0)) 
    primas_pdte_cobro_cta_anterior, 
    SUM (func('NVL', l.detrac_sobre_deposito_prim_ini, 0)) 
    detraccion_depo_ret_s_ppc_ant, 
    SUM(func('NVL', l.com_prim_dev_n_emiti_ced_ini, 0) 
    + func('NVL', l.com_prim_emit_ce_pedte_cob_ini, 0)) 
    gasto_reinteg_s_pp_cta_anterior, 
    SUM (func('NVL', l.intereses_deposito, 0)) intereses_s_depo_reemb, 
    SUM (func('NVL', l.participacion_beneficios, 0)) participacion_beneficios, 
    SUM (func('NVL', l.participacion_perdidas, 0)) participacion_perdidas, 
    AVG(cc.porcentaje_participacion) porcentaje_participacion, 
    AVG(c.porcCesGralIni) porcCesGralIni, 
    SUM (func('NVL', l.saldo_cuenta_efec_cp, 0) + func('NVL', l.depos_sobre_siniest_pdtes_fin, 0) -  func('NVL', l.depos_sobre_siniest_pdtes_ini, 0) ) saldo_cuenta_efec_cp, 
    SUM (func('NVL', l.depos_sobre_siniest_pdtes_fin, 0) ) deposito_retenido_a_X_sin, 
    SUM (func('NVL', l.depos_sobre_siniest_pdtes_ini, 0) ) deposito_reembolsado_sin 

        FROM   LiquidacionCpReaseg l, ContratoComun c, ContratoCorredor cc 
        WHERE   l.id.pais = c.pais.id 
        AND l.id.compania = c.compania.id 
        AND l.id.tipo_contrato = c.tipoContrato.id 
        AND l.id.producto = c.producto 
        AND l.id.reasegurador = c.reasegurador.id 
        AND l.id.anio_suscripcion = c.anyo  
        AND c.id = cc.id.id_contrato 
        AND l.id.trimestre=:trimestre 
        AND l.id.anio_suscripcion=:anio 
        AND l.producto.id.tipoProducto IN:tiposProducto  
        AND l.id.pais IN :paises 
        AND l.id.compania = :compania 
        AND l.corredor.id = cc.corredor.id 
        AND l.id.reasegurador=:id AND l.corredor.id=:identificadorCorredor

事情是,如果我记录生成的查询,它在FROMWHERE投影中有所不同:

FROM   Corredor t9,
         Corredor t8,
         PRODUCTO t7,
         Reasegurador t6,
         TIPO_CONTRATO t5,
         COMPANIA t4,
         PAIS t3,
         CONTRATO_COMUN t2,
         CONTRATO_CORREDOR t1,
         LIQUIDACIONES_CP_REASEG t0
 WHERE   ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( (t0.pais = t3.id_pais)
                                      AND (t0.compania = t4.id_compania))
                                    AND (t0.tipo_contrato =
                                            t5.id_tipo_contrato))
                                  AND (t0.producto = t2.producto))
                                AND (t0.reasegurador = t6.id_reasegurador))
                              AND (t0.anio_suscripcion = t2.anyo))
                            AND (t2.id_contrato = t1.id_contrato))
                          AND (t0.trimestre = 201506))
                        AND (t0.anio_suscripcion = 1991))
                      AND (t7.tipo_producto IN (1)))
                    AND (t0.pais IN (116)))
                  AND (t0.compania = 1))
                AND (t8.id_corredor = t9.id_corredor))
              AND (t0.reasegurador = 1))
            AND (t0.corredor = 0))
          AND ( ( ( ( ( ( (t3.id_pais = t2.pais)
                         AND (t4.id_compania = t2.compania))
                       AND (t5.id_tipo_contrato = t2.tipo_contrato))
                     AND (t6.id_reasegurador = t2.reasegurador))
                   AND ( (t7.tipo_producto = t0.producto)
                        AND ( (t7.compania = t0.compania)
                             AND (t7.pais = t0.pais))))
                 AND (t8.id_corredor = t0.corredor))
               AND (t9.id_corredor = t1.id_corredor)))

项目正在使用EclipseLink 2.2.0Oracle11数据库。使用SpringRoo

生成实体

生成的查询如下:

TypedQuery<Object[]> q =entityManager.createQuery(jpql+sFiltroCorredorResasegurador,Object[].class);
...
return q.getSingleResult();` 

2 个答案:

答案 0 :(得分:1)

编辑答案

我在您的选择部分中没有看到任何内容,这会导致访问ManyToOne引用。 您还试图懒惰地获取这些引用,这些引用没有任何改变。 所以,剩下的就是Where部分。当我早些时候回答你时,这就是我忽略的。

例如,表PAIS被添加到where SQL中,因为在JPQL中有一个Where l.id.pais = c.pais.id。 我敢打赌ContratoComun中有一个ManyToOne参考pais。 c.pais.id将被解析为:加载由c.pais引用的PAIS实体,然后使用属性id 加载的实体,用于选择应引用哪个“ContratoComun”。这只是一个非常复杂的例子的一部分 但我认为其他参考文献可以用同样的方式解释。

旧的过时答案

如果你的意思是,“为什么在from子句中有更多的表,然后在jpa from子句中的类”然后,(不知道你的类定义)我会猜你使用例如manyToOne引用其他类,例如“PRODUCTO”。

<击>

我不知道你的完整选择部分。但我认为实体管理器出于某种原因尝试从引用的对象中添加字段。附加条款以匹配ManyToOne对象的外键。

答案 1 :(得分:1)

我找到了解决方案。问题是他们试图将FK字段与不相关的表进行比较,即:

l.id.compania = c.compania.id

因为c.companiaManyToOneCompania类型的映射,JPQL加入cCompania在生成的sql中添加额外的参数。 对于这种情况,需要将FK映射为简单列以避免加入Compania

@Column(name = "compania",updatable=false,insertable=false) private BigDecimal compania_id;

并将查询更改为:

l.id.compania = c.compania_id