terça-feira, 11 de setembro de 2012

Merge de resultados do hql em um único objeto



A consulta mais simples possível do Hibernate é a seguinte:
from eg.Cat
Isto simplesmente retornará todas as instâncias da classe eg.Cat. Geralmente não precisamos qualificar o nome da classe, uma vez que o auto-import é o padrão. Por exemplo:
from Cat
Com o objetivo de referir-se ao Cat em outras partes da consulta, você precisará determinar um alias. Por exemplo:
from Cat as cat
Essa consulta atribui um alias a cat para as instâncias de Cat, portanto poderemos usar esse alias mais tarde na consulta. A palavra chave as é opcional. Você também pode escrever assim:
from Cat cat
Classes múltiplas podem ser envolvidas, resultando em um produto cartesiano ou união "cruzada".
from Formula, Parameter
from Formula as form, Parameter as param
É considerada uma boa prática nomear alias de consulta, utilizando uma letra minúscula inicial, consistente com os padrões de nomeação Java para variáveis locais (ex.: domesticCat).
Podemos também atribuir aliases em uma entidade associada, ou mesmo em elementos de uma coleção de valores, usando uma join. Por exemplo:
from Cat as cat
    inner join cat.mate as mate
    left outer join cat.kittens as kitten
from Cat as cat left join cat.mate.kittens as kittens
from Formula form full join form.parameter param
Os tipos de uniões suportados foram inspirados no ANSI SQL:
  • inner join
  • left outer join
  • right outer join
  • união completa (geralmente não é útil)
As construções inteirounião esquerda externa e união direita externa podem ser abreviadas.
from Cat as cat
    join cat.mate as mate
    left join cat.kittens as kitten
Você pode fornecer condições extras de união usando a palavra chave do HQL with.
from Cat as cat
    left join cat.kittens as kitten
        with kitten.bodyWeight 
> 10.0
A "fetch" join allows associations or collections of values to be initialized along with their parent objects using a single select. This is particularly useful in the case of a collection. It effectively overrides the outer join and lazy declarations of the mapping file for associations and collections. See Seção 20.1, “Estratégias de Busca ” for more information.
from Cat as cat
    inner join fetch cat.mate
    left join fetch cat.kittens
Geralmente, uma união de busca não precisa atribuir um alias, pois o objeto associado não deve ser usado na cláusula where (ou em qualquer outra cláusula). Também, os objetos associados não são retornados diretamente nos resultados da consulta. Ao invés disso, eles devem ser acessados usando o objeto pai. A única razão pela qual precisariamos de um alias é quando fazemos uma união de busca recursivamente em uma coleção adicional:
from Cat as cat
    inner join fetch cat.mate
    left join fetch cat.kittens child
    left join fetch child.kittens
Observe que a construção busca não deve ser usada em consultas invocadas usando iterate() (embora possa ser usado com scroll()). O Fetch também não deve ser usado junto com o setMaxResults() ou setFirstResult() pois essas operações são baseadas nas linhas retornadas, que normalmente contém duplicidade devido à busca das coleções, então o número de linhas pode não ser o que você espera. A Fetch não deve ser usada junto com uma condição with. É possível que seja criado um produto cartesiano pela busca de união em mais do que uma coleção em uma consulta, então tome cuidado nesses casos. Uma busca de união em várias coleções pode trazer resultados inesperados para mapeamentos do tipo bag, tome cuidado na hora de formular consultas como essas. Finalmente, observe o seguinte, abusca de união completa e busca de união direita não são importantes.
Se estiver usando o nível de propriedade busca lazy (com instrumentação de bytecode), é possível forçar o Hibernate a buscar as propriedades lazy imediatamente na primeira consulta, usando buscar todas as propriedades .
from Document fetch all properties order by name
from Document doc fetch all properties where lower(doc.name) like '%cats%'


Fonte: http://docs.jboss.org/hibernate/orm/3.5/reference/pt-BR/html/queryhql.html


Uma estratégia de busca é a estratégia que o Hibernate irá usar para recuperar objetos associados se a aplicação precisar navegar pela associação. Estratégias de Busca podem ser declaradas nos metadados de mapeamento O/R, ou sobrescritos por uma consulta HQL ou consulta com Criteria.
Hibernate3 define as seguintes estratégias de busca:
  • Join fetching - o Hibernate busca o objeto ou coleção associada no mesmo SELECT, usando um OUTER JOIN.
  • Select fetching - um segundo SELECT é usado para buscar a entidade ou coleção associada. A menos que você desabilite a busca lazy, especificando lazy="false", esse segundo SELECT será executado apenas quando você acessar a associação.
  • Subselect fetching - um segundo SELECT será usado para recuperar as coleções associadas de todas as entidades recuperadas em uma consulta ou busca anterior. A menos que você desabilite a busca lazy especificandolazy="false", esse segundo SELECT será executado apenas quando você acessar a associação.
  • Batch fetching - uma opção de otimização para selecionar a busca. O Hibernate recupera um lote de instâncias ou entidades usando um único SELECT, especificando uma lista de chaves primárias ou chaves externas.
O Hibernate distingue também entre:
  • Immediate fetching - uma associação, coleção ou função é imediatamente recuperada, quando o proprietário for carregado.
  • Lazy collection fetching - a coleção é recuperada quando a aplicação invoca uma operação sobre aquela coleção. Esse é o padrão para coleções.
  • "Extra-lazy" collection fetching - elementos individuais de uma coleção são acessados a partir do banco de dados quando necessário. O Hibernate tenta não buscar a coleção inteira dentro da memória a menos que seja absolutamente necessário. Isto é indicado para coleções muito grandes.
  • Proxy fetching: uma associação de um valor é carregada quando um método diferente do getter do identificador é invocado sobre o objeto associado.
  • "No-proxy" fetching - uma associação de um único valor é recuperada quando a variável da instância é acessada. Comparada à busca proxy, esse método é menos preguiçoso (lazy); a associação é buscada até mesmo quando somente o identificador é acessado. Ela é mais transparente, já que não há proxies visíveis para a aplicação. Esse método requer instrumentação de bytecodes em build-time e é raramente necessário.
  • Lazy attribute fetching: um atributo ou associação de um valor é buscado quanto a varíavel da instância é acessada. Esse método requer instrumentação de bytecodes em build-time e é raramente necessário.
Nós temos aqui duas noções ortogonais: quando a associação é buscada e como ela é buscada. É importante que você não os confuda. Nós usamos fetch para ajustar o desempenho. Podemos usar lazy para definir um contrato para qual dado é sempre disponível em qualquer instância desconectada de uma classe particular.


HQL: Fetch Join Collections from Eager Table


O segredo é :

SELECT e FROM Escola e JOIN FETCH e.aulas a;

para que o FETCH funcione é necessário que todos os relacionamentos sejam declarados na clausula  FROM e que um único objeto seja especificado na clausula SELECT

No exemplo acima o objeto Escola possui uma Collection de Aula, sendo assim eu quero que os resultados sejam resolvidos em uma única consulta, então defino o label "e" que representa a Escola no select e no FROM defino os relacionamentos com a clausula FETCH após os joins.

Com isso em uma única consulta o objeto será preenchido.



Nenhum comentário:

Postar um comentário