Hibernate: Parse / Traduzir HQL de parte a obter apelido pares de classe, nome da classe
-
11-07-2019 - |
Pergunta
Pode alguém ponto-me para fora, como posso analisar / avaliar HQL e obter mapa onde chave é a tabela alias e valor -. Nome da classe totalmente qualificado
por exemplo. para HQL
SELECIONAR a.id de Foo um INNER JOIN a.test b
Gostaria de ter pares:
a, package1.Foo
b. package2.TestClassName
É relativamente fácil de fazer para conjunto de resultados
HQLQueryPlan hqlPlan = ((SessionFactoryImpl)sf).getQueryPlanCache().getHQLQueryPlan( getQueryString(), false, ((SessionImpl)session).getEnabledFilters() ); String[] aliases = hqlPlan.getReturnMetadata().getReturnAliases(); Type[] types = hqlPlan.getReturnMetadata().getReturnTypes();
Solução
Quase uma boa maneira de fazê-lo, mas parece que você pode obter o AST através de algumas interfaces internas e percorrer o seguinte:
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);
Portanto, este parece recuperar os de alias-mapeamentos da consulta compilada, mas eu seria muito cuidado ao usar esta solução: ele typecasts objetos para subclasses geralmente não visíveis a uma hibernate-cliente e interpreta a AST baseado em adivinhar a semântica os diferentes nós. Isso pode não funcionar em todos os HQL-indicações, e pode não funcionar ou ter um comportamento diferente, em um futuro hibernate-versão.
Outras dicas
Eu encontrei solução certa para a minha pergunta. Seu post original era quase certo, exceto que parte:
if(node.getType() == SqlTokenTypes.FROM_FRAGMENT || node.getType() == SqlTokenTypes.JOIN_FRAGMENT) {
FromElement id = (FromElement)node;
System.out.println(node+": "+id.getClassAlias()+" - "+id.getClassName());
}
Por favor, corrija a sua resposta resposta e eu aceitá-lo.