Hibernate: analyser / traduire HQL de la partie pour obtenir un alias de classe de paires, nom de classe

StackOverflow https://stackoverflow.com/questions/324105

Question

Quelqu'un peut-il me signaler comment analyser / évaluer HQL et obtenir un mappage où clé est un alias de table et une valeur - nom de classe qualifié complet.

E.g. pour HQL

  

SÉLECTIONNER a.id dans Foo a INNER JOIN a.test b

Je souhaite avoir des paires:

a, package1.Foo

b. package2.TestClassName

C'est relativement facile à faire pour un 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 les détails ici .

Était-ce utile?

La solution

Ce n'est pas un bon moyen de le faire, mais il semble que vous pouvez obtenir l'AST via certaines interfaces internes et traverser cette page:

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);

Cela semble donc récupérer les mappages d'alias de la requête compilée, mais je ferais très attention en utilisant cette solution: elle diffuse des objets dans des sous-classes généralement invisibles pour un client hibernate et interprète l'AST en se basant sur la sémantique de les différents nœuds. Cela pourrait ne pas fonctionner sur toutes les instructions HQL, et ne pas fonctionner ou avoir un comportement différent sur une future version en veille prolongée.

Autres conseils

J'ai trouvé la bonne solution à ma question. Votre message original était presque correct à l'exception de cette 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.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top