12

我知道您可以{alias}用来引用 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()}))

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

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

4

1 回答 1

15

进行了一些谷歌搜索后,这似乎是不可能的 - Hibernate 只允许{alias}SQLProjection. 然而,我确实发现了这个关于Hibernate JIRA 页面限制的问题。

有人通过一个新类提交了一个允许在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:getOuterQueryTranslator和中的以下私有方法getAliasedCriteria。为了在不修改 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);

希望这将帮助其他面临同样问题的人。

于 2011-10-20T07:41:22.660 回答