Java – Hibernate: Parse/Translate HQL FROM part to get pairs class alias, class name

hibernatehqljava

Can anyone point me out, how can I parse/evaluate HQL and get map where key is table alias and value – full qualified class name.

E.g. for HQL

SELECT a.id from Foo a INNER JOIN a.test b

I wish to have pairs:

a, package1.Foo

b. package2.TestClassName

It's relatively easy to do for result set

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

See details here.

Best Answer

Hardly a good way of doing it, but it seems you can get the AST through some internal interfaces and traverse this:

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

So this seems to retrieve the alias-mappings from the compiled query, but I would be very careful using this solution: it typecasts objects to subclasses not usually visible to a hibernate-client and interprets the AST based on guessing the semantics of the different nodes. This might not work on all HQL-statements, and might not work, or have different behaviour, on a future hibernate-version.

Related Topic