Ссылка на внешние псевдонимы запросов критериев из SQLProjection

Я знаю, что вы можете использовать {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()}))

где i - это псевдоним из запроса внешних критериев. В приведенном выше коде исключается исключение SQL, указывающее, что i.powerRestarts не может быть найден.

Можно ли ссылаться на псевдоним без корня из SQLProjection?

Ответ 1

Сделав некоторый поиск в googling, кажется, что это невозможно - Hibernate разрешает только включение псевдонима корневого объекта с помощью {alias} в строку SQL SQLProjection. Однако я нашел эту проблему в отношении ограничения на страницах JIRA Hibernate.

Кто-то любезно предоставил патч, который позволяет использовать псевдонимы без полномочий 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.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);

Надеюсь, это поможет любому, кто сталкивается с одной и той же проблемой.