Hibernate:从部分解析/转换HQL,以获得类别名、类名对

2022-04-03 00:00:00 java Hibernate hql

谁能告诉我,如何解析/评估HQL并获得key是表别名和值的全限定类名的映射。

例如HQL

从foo a内部联接中选择a.id。测试b

我希望有对:

a,Package1.foo

b.Package2.TestClassName

对结果集执行此操作相对容易

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

参见details here。


解决方案

这不是一个好方法,但您似乎可以通过一些内部接口获取AST并遍历以下内容:

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);
因此,这似乎是从编译后的查询中检索别名映射,但我在使用此解决方案时会非常小心:它将对象类型转换为Hibernate客户端通常不可见的子类,并基于猜测不同节点的语义来解释AST。这可能不适用于所有HQL语句,并且可能不适用于未来的Hibernate版本,或者具有不同的行为。

相关文章