Hibernate: Parse / Traduzir HQL de parte a obter apelido pares de classe, nome da classe

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

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

detalhes aqui .

Foi útil?

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.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top