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

Why JPQL generated query differs from original

我正在审查这样的 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();` 

已编辑答案

我在您的 select 部分中没有看到任何会导致访问 ManyToOne 引用的内容。 您还尝试延迟获取这些引用,这并没有改变任何东西。 因此,剩下的就是 Where 部分。这就是我之前回答您时忽略的内容。

例如,table PAIS 被添加到 where SQL 中,因为在 JPQL 中有一个 Where 术语 l.id.pais = c.pais.id。 我敢打赌,在 ContratoComun 中有一个 ManyToOne 参考 pais。 c.pais.id会解析为:加载c.pais引用的PAIS的实体,然后使用c.pais的属性id 加载到 select 的实体应该引用 "ContratoComun"。这只是一个非常复杂的例子的一部分 但我认为其他参考资料也可以用同样的方式解释。

旧的已过时的答案

如果你的意思是 "Why are there more tables in the from clause then classes in the jpa from clause" 那么,(不知道你的 class 定义)我猜你使用例如manyToOne 对其他 class 的引用,例如"PRODUCTO".

我不知道你的完整 select 部分。但我认为实体管理器出于某种原因试图从引用的对象中添加字段。添加了额外的 where 项以匹配 ManyToOne 对象的外键。

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

l.id.compania = c.compania.id

因此 c.companiaManyToOne 映射到 Compania 类型,JPQL 加入 cCompania 在生成的 sql。 对于这种情况,需要将 FK 映射为简单列以避免连接到 Compania:

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

并将查询更改为:

l.id.compania = c.compania_id