引用外部条件查询SQLProjection中的别名

时间:2011-10-19 14:15:07

标签: java hibernate hibernate-criteria

我知道您可以使用{alias}来引用SQLProjection中的根实体:

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

我要做的是引用非root 实体的别名:

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

其中i是外部条件查询的别名。上面的代码抛出一个SQL异常,说无法找到i.powerRestarts

是否可以从SQLProjection引用非根别名?

1 个答案:

答案 0 :(得分:14)

完成了一些谷歌搜索,似乎这是不可能的 - Hibernate只允许在{alias}的SQL字符串中使用SQLProjection包含根实体别名。但我在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);

希望这可以帮助其他任何面临同样问题的人。