Sospensione: analizza / traduci la parte HQL FROM per ottenere coppie alias di classe, nome classe
-
11-07-2019 - |
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 .
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.