Senhores,
Estou tendo um comportamento indesejado quando eu faço uma query usando JPA. Quando eu executo exatamente a mesma query usando Hibernate ocorre tudo como esperado.
Quando eu utilizo a seguinte Query do JPA: from Tarefa t left outer join t.status s
Alem do Select que executa o Join da Tabela Tarefa com a tabela Status, são executados N selects para cada registro existente na tabela Status. Por exemplo são executados os selects da seguinte forma:
0:31:56,638 INFO [STDOUT] Hibernate:
select
tarefa0_.id as id8_,
tarefa0_.descricao as descricao8_,
tarefa0_.nome as nome8_,
tarefa0_.prazo as prazo8_,
tarefa0_.prioridade as prioridade8_,
tarefa0_.projeto as projeto8_,
tarefa0_.responsavel as responsa7_8_,
tarefa0_.status_id as status8_8_
from
Tarefa tarefa0_
inner join
Status status1_
on tarefa0_.status_id=status1_.id
00:31:56,640 INFO [STDOUT] Hibernate:
select
status0_.id as id6_0_,
status0_.descricao as descricao6_0_,
status0_.nome as nome6_0_
from
Status status0_
where
status0_.id=?
00:31:56,642 INFO [STDOUT] Hibernate:
select
status0_.id as id6_0_,
status0_.descricao as descricao6_0_,
status0_.nome as nome6_0_
from
Status status0_
where
status0_.id=?
00:31:56,643 INFO [STDOUT] Hibernate:
select
status0_.id as id6_0_,
status0_.descricao as descricao6_0_,
status0_.nome as nome6_0_
from
Status status0_
where
status0_.id=?
Porém se eu utilizar o Criteria do Hibernate apenas um Select é executado (exatamente como eu gostaria). Usando Criteria da seguinte forma: session.createCriteria(Tarefa.class).list()
; é executado o seguinte SQL final:
select
this_.id as id2_1_,
this_.descricao as descricao2_1_,
this_.nome as nome2_1_,
this_.prazo as prazo2_1_,
this_.prioridade as prioridade2_1_,
this_.projeto as projeto2_1_,
this_.responsavel as responsa7_2_1_,
this_.status_id as status8_2_1_,
status2_.id as id0_0_,
status2_.descricao as descricao0_0_,
status2_.nome as nome0_0_
from
Tarefa this_
left outer join
Status status2_
on this_.status_id=status2_.id
Alguém consegue me explicar porque isso ocorre no JPA, eu já tentei de tudo.
A única forma que eu consegui fazer com que a consulta no JPA executasse apenas um select foi fazendo o seguinte:
Select t, s.nome from Tarefa t left outer join t.status s
Porém desta forma ele me retorna uma lista de Tarefas (a que eu gostaria) e também uma lista de Status. Sendo assim eu preciso fazer um FOR percorrendo a lista retornada e criando outra lista apenas com contendo objetos do tipo Tarefa, desta forma:
List<Tarefa> listaTarefas = new ArrayList<Tarefa>();
for (Object obj: resultadoConsulta){
if(obj instanceof Tarefa){
listaTarefas.add(obj);
}
}
Usando Criteria do Hibernate eu não preciso fazer nada disso, ele me traz uma lista de Tarefas certinho. Será que a API de Criteria por trás dos panos faz algo parecido com esse FOR, sendo por isso que ele me traz apenas a lista de tarefas? Eu pouco performático ter que ficar utilizando esse FOR depois de fazer a consulta no banco, eu queria trazer tudo de uma vez certinho…