2008-11-27 61 views
3

任何人都可以指出,我如何解析/評估HQL並獲取映射,其中鍵是表別名和值 - 全限定類名。休眠:解析/翻譯HQL從部分獲得對類別別名,類名稱

E.g.對於HQL

從富

SELECT a.id一個INNER JOIN a.test b

我希望有對:

一個,package1.Foo

灣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

回答

4

幾乎沒有這樣做的一個很好的方式,但似乎你可以通過一些內部接口獲得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-client通常不可見的子類,並根據猜測不同節點的語義來解釋AST。這可能不適用於所有HQL語句,並且在將來的hibernate版本上可能無法工作或具有不同的行爲。

+0

我基於內部API(標準窗格等)動態生成HQL,而過濾條件(即WHERE部分)需要知道HQL中每個類的別名。 – FoxyBOA 2008-12-19 16:33:00

0

我找到了適合我的問題的解決方案。您原來的帖子幾乎是正確的,除了那部分:

if(node.getType() == SqlTokenTypes.FROM_FRAGMENT || node.getType() == SqlTokenTypes.JOIN_FRAGMENT) { 
FromElement id = (FromElement)node; 
System.out.println(node+": "+id.getClassAlias()+" - "+id.getClassName()); 
} 

請更正您的答案答案,我接受它。