我知道您可以使用{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引用非根别名?
答案 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
中的以下私有方法: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);
希望这可以帮助其他任何面临同样问题的人。