简体   繁体   中英

Why JPQL generated query differs from original

I am reviewing a JPQL query like that:

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

thing is that if i log the generated query it differs in the FROM and WHERE projections:

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

Project is using EclipseLink 2.2.0 and Oracle11 Database. Entities are generated using SpringRoo

Query is generated like that:

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

Edited Answer

I've seen nothing in your select part, that would cause access to the ManyToOne References. You also tried to lazy fetch these references, which did not change anything. So, all that is left is the Where part. And that's what I've overlooked, when I answered you earlier.

For example the table PAIS is added to the where SQL because in JPQL there is a Where term l.id.pais = c.pais.id . I Would bet that there is a ManyToOne reference pais in ContratoComun. c.pais.id will be resolved to: load the entity of PAIS that is referenced by c.pais and then use the attribute id of the loaded entity to select which "ContratoComun" should be referenced. This is only one part of a really complex example but I think the other references could be explained in the same way.

Old obsolete answer

If you mean, "Why are there more tables in the from clause then classes in the jpa from clause" then, (without knowing your class definitions) I would guess that you use eg manyToOne references to other classes like eg "PRODUCTO".

\n

I don't know your complete select part. But I think the entity manager tries to add fields from the referenced objects for some reason. The additional where terms are added to match the foreign key of the ManyToOne objects.

I've found the solution. Problem was that they were trying to compare to FK fields in to unrelated tables, ie:

l.id.compania = c.compania.id

so as c.compania is a ManyToOne mapping to a Compania type, JPQL joins c and Compania adding extra parameters in the generated sql. For this case, mapping the FK as a simple column is needed to avoid joining to Compania :

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

and change the query to:

l.id.compania = c.compania_id

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM