Hibernate monta o SELECT errado (RESOLVIDO)

Olá

estou montando uma query relativamente complexa. Ela deve pegar dados de um funcionário, como nome, registro, além de dados de do cargo e empresa atuais desse funcionário. Como o banco de dados armazena todo o histórico de cargos e empresa dos funcionários, a pesquisa para pegar os dados atuais fica um pouco complexa.

O problema é Hibernate está colocando a ordem das “frases” SQL erroneamente. Minha Query em JPQL é a seguinte:

" SELECT new model.FunAtualVO "
" ("
"		f.atrRegistro, f.pes.atrNomePessoa, f.atrDataAdmissao, "
"		fc.id.atrAnoMesInicioCargo, fc.car.atrCodCbo, fc.car.atrNomeCargo,"
"		fe.emp.atrNomeEmpresa, fe.emp.atrNomeEmpresaAbreviado, fe.id.atrAnoMesInicioEmpresa"
" ) "
"	FROM Fun f, IN(f.funCars) fc, IN(f.funEmps) fe "
" WHERE fc.atrAnoMesFinalCargo = 999912"
"	AND fe.atrAnoMesFinalEmpresa = 999912"
"	AND f.atrIdFuncionario = :idFuncionario");

que está sendo traduzida para o seguinte script SQL (estou usando MySQL):

SELECT
SELECT
        fun0_.atrRegistro as col_0_0_,
        pes3_.atrNomePessoa as col_1_0_,
        fun0_.atrDataAdmissao as col_2_0_,
        car4_.atrNomeCargo as col_3_0_,
        car4_.atrCodCbo as col_4_0_,
        funcars1_.atrAnoMesInicioCargo as col_5_0_,
        emp6_.atrNomeEmpresa as col_6_0_,
        emp6_.atrNomeEmpresaAbreviado as col_7_0_,
        funemps2_.atrAnoMesInicioEmpresa as col_8_0_
    from
        Fun fun0_
    inner join
        FunCar funcars1_
            on fun0_.atrIdFuncionario=funcars1_.AtrIdFuncionario,
		Car car4_
    inner join
        FunEmp funemps2_
            on fun0_.atrIdFuncionario=funemps2_.AtrIdFuncionario,
        Emp emp6_,
        Pes pes3_
    where
        funcars1_.AtrIdCargo=car4_.atrIdCargo
        and funemps2_.AtrIdEmpresa=emp6_.atrIdEmpresa
        and fun0_.AtrIdPessoa=pes3_.atrIdPessoa
        and funcars1_.atrAnoMesFinalCargo=999912
        and funemps2_.atrAnoMesFinalEmpresa=999912
        and fun0_.atrIdFuncionario=? limit ?

Vejam que a tabela Car car4 está sendo declarada entre a Fun e a FunEmp, logo é gerado o seguinte erro:

Error Code: 1054. Unknown column ‘fun0_.atrIdFuncionario’ in ‘on clause’

Se entro no MySQL e altero a ordem da declaração das tabelas para o modo abaixo, a query roda normalmente:

from
       		Car car4_, Fun fun0_
    inner join
        FunCar funcars1_
            on fun0_.atrIdFuncionario=funcars1_.AtrIdFuncionario
    inner join
        FunEmp funemps2_
            on fun0_.atrIdFuncionario=funemps2_.AtrIdFuncionario,
        Emp emp6_,
        Pes pes3_

Existe alguma maneira de manipular a montagem desse SELECT para que não ocorra o erro?

Obrigado!!

Daria para você criar a mesma na mão.

Pode ser que o errado ai seja seu mapeamento.

Neste tutorial tem um exemplo.

http://www.mkyong.com/hibernate/hibernate-query-examples-hql/

Por “na mão” você se refere a usar SQL Nativo? Queria evitar isso a todo custo, pois o aplicativo deve rodar em diferentes bancos de dados.

Quanto ao mapeamento, acredito que está correto, pois as demais queries mais simples, rodam sem problema. E também as entidades foram criadas automaticamente pelo Eclipse através do esquema de tabelas do banco de dados.

[quote=felipe_gdr]Por “na mão” você se refere a usar SQL Nativo? Queria evitar isso a todo custo, pois o aplicativo deve rodar em diferentes bancos de dados.

Quanto ao mapeamento, acredito que está correto, pois as demais queries mais simples, rodam sem problema. E também as entidades foram criadas automaticamente pelo Eclipse através do esquema de tabelas do banco de dados.[/quote]Se você trocar o in por join?

Herbert,

alterei para a query abaixo e continua exatamente igual:

" SELECT new model.FunAtualVO "
" ("
"		f.atrRegistro, f.pes.atrNomePessoa, f.atrDataAdmissao, " 
"		fc.id.atrAnoMesInicioCargo, fe.id.atrAnoMesInicioEmpresa, "
"		fc.car.atrNomeCargo, fc.car.atrCodCbo, "
"		fe.emp.atrNomeEmpresa, fe.emp.atrNomeEmpresaAbreviado"
" ) "
"	FROM Fun f " 
"		JOIN f.funCars fc " 
"		JOIN f.funEmps fe "
" WHERE fe.atrAnoMesFinalEmpresa = 999912" 
"		AND fc.atrAnoMesFinalCargo = 999912"
"		AND f.atrIdFuncionario = :idFuncionario"
    " SELECT new model.FunAtualVO "  
    " ("  
    "       f.atrRegistro, f.pes.atrNomePessoa, f.atrDataAdmissao, "   
    "       fc.id.atrAnoMesInicioCargo, fe.id.atrAnoMesInicioEmpresa, "  
    "       c.atrNomeCargo, c.atrCodCbo, "  
    "       fe.emp.atrNomeEmpresa, fe.emp.atrNomeEmpresaAbreviado"  
    " ) "  
    "   FROM Fun f "   
    "       JOIN f.funCars fc "   
    "       JOIN f.funEmps fe "  
    "       JOIN fc.car c "
    " WHERE fe.atrAnoMesFinalEmpresa = 999912"   
    "       AND fc.atrAnoMesFinalCargo = 999912"  
    "       AND f.atrIdFuncionario = :idFuncionario"  

na mosca pmlm! Problema resolvido!

Valeu e abraço!

Deixares vários pontos no mesmo atributo (fc.car.atrCodCbo) normalmente é má ideia, exactamente porque não controlas como o SQL será gerado.