Sospensione: analizza / traduci la parte HQL FROM per ottenere coppie alias di classe, nome classe

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

Domanda

Qualcuno può indicarmi, come posso analizzare / valutare HQL e ottenere la mappa in cui la chiave è alias e valore della tabella - nome di classe completo qualificato.

es. per HQL

  

SELEZIONA a.id da Foo a INNER JOIN a.test b

Vorrei avere coppie:

a, package1.Foo

b. package2.TestClassName

È relativamente facile da fare per il set di risultati

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

Vedi dettagli qui .

È stato utile?

Soluzione

Difficilmente un buon modo per farlo, ma sembra che tu possa ottenere l'AST attraverso alcune interfacce interne e attraversare questo:

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

Quindi questo sembra recuperare gli alias-mapping dalla query compilata, ma starei molto attento usando questa soluzione: scrive gli oggetti in sottoclassi di solito non visibili a un client ibernato e interpreta l'AST basato sull'indovinare la semantica di i diversi nodi. Questo potrebbe non funzionare su tutte le istruzioni HQL e potrebbe non funzionare, o avere un comportamento diverso, su una futura versione ibernata.

Altri suggerimenti

Ho trovato la soluzione giusta per la mia domanda. Il tuo post originale era quasi corretto tranne quella parte:

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

Correggi la tua risposta e la accetto.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top