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

#java #hibernate #hibernate-criteria

#ява #переход в спящий режим #переход в спящий режим-критерии #java

Вопрос:

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

После некоторого поиска в Google кажется, что это невозможно — Hibernate разрешает включение псевдонима корневого объекта, используя {alias} , в строку SQL SQLProjection . Однако я обнаружил эту проблему, касающуюся ограничения на страницах гибернации 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 . Чтобы заставить это работать без изменения источника гибернации, я использовал отражение:

 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);
  

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