2008-11-27 7 views
3

Quelqu'un peut-il me signaler, comment puis-je analyser/évaluer HQL et obtenir la carte où la clé est l'alias et la valeur - nom de classe complet qualifié.Hibernate: Parse/Translate HQL FROM partie pour obtenir l'alias de classe paires, nom de classe

E.g. pour HQL

SELECT a.id de Foo une INNER JOIN a.test b

Je souhaite avoir des paires:

a, package1.Foo

b. package2.TestClassName

Il est relativement facile à faire pour jeu de résultats

HQLQueryPlan hqlPlan = ((SessionFactoryImpl)sf).getQueryPlanCache().getHQLQueryPlan(getQueryString(), false, ((SessionImpl)session).getEnabledFilters()); 
String[] aliases = hqlPlan.getReturnMetadata().getReturnAliases(); 
Type[] types = hqlPlan.getReturnMetadata().getReturnTypes(); 

Voir details here.

Répondre

4

A peine une bonne façon de le faire, mais il semble que vous pouvez obtenir l'AST à travers des interfaces internes et traversent ceci:

QueryTranslator[] translators = hqlPlan.getTranslators(); 
AST ast = (AST)((QueryTranslatorImpl)translators[0]).getSqlAST(); 
    new NodeTraverser(new NodeTraverser.VisitationStrategy() { 
    public void visit(AST node) { 
     if(node.getType() == SqlTokenTypes.FROM_FRAGMENT || node.getType() == SqlTokenTypes.JOIN_FRAGMENT) { 
      FromElement id = (FromElement)node; 
      System.out.println(node+": "+id.getClassAlias()+" - "+id.getClassName()); 
     } 
    } 
}).traverseDepthFirst(ast); 

Donc, cela semble récupérer les alias-correspondances de la requête compilée, mais Je serais très prudent en utilisant cette solution: il convertit les objets en sous-classes qui ne sont généralement pas visibles par un hibernate-client et interprète l'AST en supposant la sémantique des différents nœuds. Cela pourrait ne pas fonctionner sur toutes les instructions HQL, et pourrait ne pas fonctionner, ou avoir un comportement différent, sur une future version d'hibernate.

+0

Je génère dynamiquement HQL basé sur notre API interne (volets de critères, etc.) et pour les conditions de filtrage (c'est-à-dire partie WHERE) besoin de connaître l'alias pour chaque classe dans le HQL. – FoxyBOA

+0

Ressemble à SqlTokenTypes.ALIAS_REF n'est pas ce que je cherche. Dans mon exemple ci-dessus, le résultat sera "a, paquet1.Foo", mais j'ai aussi besoin de "b, paquet2.TestClassName". Je veux dire ALIAS_REF processus "SELECT" partie au lieu de "FROM". – FoxyBOA

+0

Concernant votre question sur l'utilisation de l'API Criteria. J'ai deux raisons: 1. Legacy code 2. HQL vous permet de construire ce que l'on appelle des requêtes de rapport (extraire exactement les données dont vous avez besoin et ne pas construire l'objet entier). Voir le lien pour plus de détails http://rongou.blogspot.com/2005/08/hibernate-report-query.html – FoxyBOA

0

J'ai trouvé la bonne solution pour ma question. Votre message original était presque correct sauf la partie:

if(node.getType() == SqlTokenTypes.FROM_FRAGMENT || node.getType() == SqlTokenTypes.JOIN_FRAGMENT) { 
FromElement id = (FromElement)node; 
System.out.println(node+": "+id.getClassAlias()+" - "+id.getClassName()); 
} 

Veuillez corriger votre réponse et je l'accepte.

Questions connexes