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


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

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

我想要做的是引用a的别名 非根 实体:

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

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

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


11367
2017-10-19 14:15


起源



答案:


做了一些谷歌搜索,似乎这是不可能的 - Hibernate只允许使用包含根实体别名 {alias} 在SQL的字符串中 SQLProjection。然而我找到了 关于限制的这个问题 在Hibernate JIRA页面上。

有人提交了一个允许在其中使用非root别名的补丁 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.CriteriaQueryTranslatorgetOuterQueryTranslator 和 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);

希望这将有助于其他任何面临同样问题的人。


13
2017-10-20 07:41