2011-10-19 50 views
10

據我所知,您可以使用{alias}指根實體SQLProjection內:引用外部條件查詢別名從SQLProjection內

Projections.sqlProjection("MIN({alias}.field) as value", new String[]{"value"}, new Type[]{new LongType()})) 

我所試圖做的是引用一個別名爲非根實體:

Projections.sqlProjection("MIN(i.powerRestarts) as value", new String[]{"value"}, new Type[]{new LongType()})) 

i其中從外條件查詢的別名。上面的代碼會拋出一個SQL異常,說明找不到i.powerRestarts

是否可以從SQLProjection中引用非根別名?

回答

12

做了一些Google搜索後,看起來這是不可能的 - Hibernate只允許在SQLProjection的SQL字符串中使用{alias}包含根實體別名。然而,我在Hibernate JIRA頁面上找到了this issue regarding the limitation

有人親切地提交了一個補丁,允許在SQLProjection字符串中使用非根別名,通過新的RestrictionsExt類。使用來自問題我的例子:

Projections.sqlProjection("MIN(i.powerRestarts) as value", new String[]{"value"}, new Type[]{new LongType()})) 

別名i現在可以參考如下:

RestrictionsExt.sqlProjection("MIN({i}.powerRestarts) as value", "value", new LongType()) 

我不得不修改靜態RestrictionsExt.sqlProjection方法允許列別名類型的規格("value" )(這裏定義爲LongType),因爲補丁不允許這樣做,默認爲StringType

修補程序中的SQLAliasedProjection類還需要訪問org.hibernate.loader.criteria.CriteriaQueryTranslator中的以下私有方法:getOuterQueryTranslatorgetAliasedCriteria。爲了得到這個沒有修改Hibernate源工作,我曾經反思:

cri = ((org.hibernate.loader.criteria.CriteriaQueryTranslator) criteriaQuery).getAliasedCriteria(alias); 

改爲:

Method m = ((org.hibernate.loader.criteria.CriteriaQueryTranslator) criteriaQuery).getClass().getDeclaredMethod("getAliasedCriteria", String.class); 
m.setAccessible(true); 
cri = (Criteria) m.invoke(((org.hibernate.loader.criteria.CriteriaQueryTranslator) criteriaQuery), alias); 

希望這將有助於其他人面臨同樣的問題。