#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);
Надеюсь, это поможет всем, кто еще сталкивается с такой же проблемой.