Hibernate + Left Outer Join

Boa Noite,

Estou enfrentando um problema com o Hibernate, ele não está listando os registros com propriedades nulas.
Por exemplo:

Usando a query abaixo irá retornar todos os orçamentos

No entanto, se eu quero filtrar um campo específico, de algum relacionamento da tabela, como segue abaixo:

Os orçamentos que não tem cliente vinculado não serão exibidos. Tentei utilizar LEFT JOIN para trazer todos, independente se estão nulos. Mas, não resolveu.

Como posso fazer isso?

Não intendo muito de hql , mas tente FROM ORCAMENTO where orcamento.cliente.nome = " qualquer coisa ";
esqueça join com hibernate, ele vai se encarregar de fazer isso pra você.

de uma olhada na api Criteria tbm, é uma otima opção pra fugir do hql.

[quote=RafaelViana]Boa Noite,

Estou enfrentando um problema com o Hibernate, ele não está listando os registros com propriedades nulas.
Por exemplo:

Usando a query abaixo irá retornar todos os orçamentos

No entanto, se eu quero filtrar um campo específico, de algum relacionamento da tabela, como segue abaixo:

Os orçamentos que não tem cliente vinculado não serão exibidos. Tentei utilizar LEFT JOIN para trazer todos, independente se estão nulos. Mas, não resolveu.

Como posso fazer isso?
[/quote]

se você não especificar o left outer join não virão orçamentos que não tem um cliente vinculado (não faço ideia de como isso poderia acontecer mas não vou entrar nessa parte :shock: )
inclusive no caso do exeplo que você colocou não está aplicando filtro nenhum, está selecionando o nome do cliente e não filtrando ele inclusive se for para filtrar o nome do cliente, não tem sentido mesmo virem orçamentos que não tem cliente, você não poderia filtrar, o cliente não existe…mas pra isso não precisa do join. Bom eu não sei se ficou claroo que você quer… alguns exemplos

//retorna orçamentos sem cliente ou com nome especifico de cliente
select o from orcamento o where o.cliente is null or o.cliente.nome = :nomeCliente

//idem com ocliente preenchido mesmo que seja lazy
select o from orcamento o left outer join fetch o.cliente c where o.cliente is null or o.cliente.nome = :nomeCliente

//retorna os clientes que tenham orçamento
select c from cliente c where c.orcamentos is not null

[quote=maior_abandonado][quote=RafaelViana]Boa Noite,

Estou enfrentando um problema com o Hibernate, ele não está listando os registros com propriedades nulas.
Por exemplo:

Usando a query abaixo irá retornar todos os orçamentos

No entanto, se eu quero filtrar um campo específico, de algum relacionamento da tabela, como segue abaixo:

Os orçamentos que não tem cliente vinculado não serão exibidos. Tentei utilizar LEFT JOIN para trazer todos, independente se estão nulos. Mas, não resolveu.

Como posso fazer isso?
[/quote]

se você não especificar o left outer join não virão orçamentos que não tem um cliente vinculado (não faço ideia de como isso poderia acontecer mas não vou entrar nessa parte :shock: )
inclusive no caso do exeplo que você colocou não está aplicando filtro nenhum, está selecionando o nome do cliente e não filtrando ele inclusive se for para filtrar o nome do cliente, não tem sentido mesmo virem orçamentos que não tem cliente, você não poderia filtrar, o cliente não existe…mas pra isso não precisa do join. Bom eu não sei se ficou claroo que você quer… alguns exemplos

//retorna orçamentos sem cliente ou com nome especifico de cliente
select o from orcamento o where o.cliente is null or o.cliente.nome = :nomeCliente

//idem com ocliente preenchido mesmo que seja lazy
select o from orcamento o left outer join fetch o.cliente c where o.cliente is null or o.cliente.nome = :nomeCliente

//retorna os clientes que tenham orçamento
select c from cliente c where c.orcamentos is not null[/quote]

Especifiquei o LEFT OUTER JOIN na query e mesmo assim não listou os orçamentos com clientes nulos. O cliente nulo no orçamento é só um exemplo (sim, isso seria um absurdo)

Por exemplo, para fazer a listagem de todos os orçamentos em vez de pesquisar o objeto inteiro com “from Orcamento”, eu faço uma busca apenas por campo específicos para otimizar a busca, já que somente esses campos serão necessários mostrar. Ex: “SELECT cliente.nome, condicaoPagamento.nome FROM Orcamento”.

Isso irá buscar somente esses dois campos que somente esses serão mostrados na listagem. Após selecionar o item na lista ele carrega todo o objeto para mostrar todos os dados, porém na lista somente será buscado o ncessário. Nesse caso acima, se tivesse um orçamento que não foi especificada a condição de pagamento ela não apareceria na listagem.

você deixou no mesmo esquema que eu disse no primeiro exemplo, usando o or? poste como vocÊ deixou sua query.

Se usar o LEFT OUTER JOIN sem o OR não funciona. Usando o OR (como vocẽ mencionou) funciona.

Ficaria algo assim:
“WHERE (cliente is null OR cliente is not null)”

Fica meio estranho, mas funciona =) (ou isso que estou fazendo é completamente errado?)
A perfomance pelo que percebi é um pouco pior, mas nenhum absurdo.

na ordem, o inner join torna a consulta mais lenta, o left ou right join torna um pouco mais lenta ainda e o full outer join ainda mais lenta.

o motivo de funcionar é o seguinte: se o seu cliente está nulo dentro de orcamento, como que orcamento.cliente.nome = “qualquercoisa” ?

cliente está nulo então a menos que você compare com null o cliente qualquer coisa do tipo vai dar false… foi usado o or para aceitar ambos os casos, o cliente nulo e cas não esteja nulo, com o nome especifico…

//retorna orçamentos sem cliente ou com nome especifico de cliente
select o from orcamento o where o.cliente is null or o.cliente.nome = :nomeCliente

//idem com ocliente preenchido mesmo que seja lazy
select o from orcamento o left outer join fetch o.cliente c where o.cliente is null or o.cliente.nome = :nomeCliente

//retorna os clientes que tenham orçamento
select c from cliente c where c.orcamentos is not null

Obrigado pela dica, estava com o problema de campos nulos no left join e isso resolveu.