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

Ekc*_*erK 12 java hibernate hibernate-criteria

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

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

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

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

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

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

Ekc*_*erK 14

做了一些谷歌搜索后,似乎这是不可能的--Hibernate只允许{alias}在SQL的字符串中包含root实体别名SQLProjection.但是,我确实发现了有关 Hibernate JIRA页面限制的问题.

有人提交了一个补丁,允许SQLProjection通过一个新RestrictionsExt类在字符串中使用非根别名.使用我的问题示例:

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

别名i现在可以引用为:

RestrictionsExt.sqlProjection("MIN({i}.powerRestarts) as value", "value", new LongType())
Run Code Online (Sandbox Code Playgroud)

我不得不修改静态RestrictionsExt.sqlProjection方法以允许指定列别名("value")(此处定义为LongType)的类型,因为补丁不允许这样并且默认为StringType.

补丁中的SQLAliasedProjection类还需要访问以下私有方法org.hibernate.loader.criteria.CriteriaQueryTranslator:getOuterQueryTranslatorgetAliasedCriteria.为了在不修改Hibernate源的情况下使其工作,我使用了反射:

cri = ((org.hibernate.loader.criteria.CriteriaQueryTranslator) criteriaQuery).getAliasedCriteria(alias);
Run Code Online (Sandbox Code Playgroud)

改为:

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);
Run Code Online (Sandbox Code Playgroud)

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