2012-08-17 9 views
1

J'ai un morceau de code semblable au suivant:Hibernate Optimisation des requêtes

public void doQuery(final Baz baz){ 
    final Query query = getSessionFactory().getCurrentSession().createQuery(
      "select distinct foo from Foo as foo "+ 
      "join foo.a as a"+ 
      "join foo.b as b "+ 
      "join b.c as c "+ 
      "where baz=:baz" 
      ); 
    query.setParameter("baz", baz); 
    final List<Foo> list = query.list(); 

    for (final Foo foo : list) { 
     final Set<C> cSet = foo.getB().getCs(); 
     final String value = foo.getSomeValue(); 
     for (final C c : cSet) {     
      final Long key = c.getSomeLong(); 
      // Do stuff with key and value 
     } 
    } 
    } 

Chaque fois que la boucle est exécuté, il sera exécuter des requêtes de mise en veille prolongée supplémentaires dans les coulisses pour tirer les données supplémentaires (puisque les objets sont marqué comme paresseux chargé). Passer d'un objet à l'autre n'est pas souhaitable car les autres classes qui utilisent le POJO n'ont pas besoin de ces données.

De toute évidence, le code ci-dessus peut créer un goulot d'étranglement, ce que je voudrais éviter. Y a-t-il une manière spécifique à l'hibernation (c'est-à-dire aucun SQL natif) de modifier la requête pour ramener seulement les données nécessaires en un coup?

Je suis bien d'avoir la requête renvoie une chaîne [] [] avec col1 comme la clé et col2 comme valeur au lieu de retourner Foo

Mise à jour:

J'ai changé la requête juste retour les clés/valeurs nécessaires

« , sélectionnez c.id distinct, foo.someValue de ...

+1

Si je comprends bien, le "chargement paresseux" peut-être ce que vous cherchez. – jrochette

+0

Commencez par régler votre requête sql, puis convertissez-la en requête Hibernate. Couple de choses, essayez d'éviter l'utilisation de "distinct" qui est lourd, essayez également de réduire le nombre de jointures. –

+0

Mais le chargement paresseux n'effectuera-t-il pas essentiellement les mêmes requêtes supplémentaires? Je ne suis pas sûr si je veux exécuter le chargement impatient sur le POJO parce que l'autre code utilise cette classe et n'a pas besoin de ces objets supplémentaires. C'est pourquoi j'espérais pouvoir le faire dans une requête (bien qu'au lieu de renvoyer un Foo j'imagine qu'il retournerait un String [] où col1 est la clé et col2 est la valeur) – user973479

Répondre

0

Comme je vous comprends la question que vous ne voulez pas avoir la collection désireux par défaut, mais dans ces cas concret/méthode chercher tout dans une requête?!

Voici le fragment de la documentation mise en veille prolongée à ce sujet:

A « chercher » join permet aux associations ou collections de valeurs à initialisés avec leurs objets parents en utilisant une seule sélection. Ceci est particulièrement utile dans le cas d'une collection. Il remplace effectivement les jointures externes et les déclarations paresseuses du fichier de mappage pour les associations et les collections. Voir Section 19.1, «Récupération des stratégies» pour plus d'informations.

from Cat as cat 
    inner join fetch cat.mate 
    left join fetch cat.kittens 

http://docs.jboss.org/hibernate/orm/3.3/reference/en/html/queryhql.html