Как избежать зарезервированных слов в HQL Hibernate - PullRequest
14 голосов
/ 16 апреля 2011

Я использую следующий запрос, чтобы получить java.util.Map с индексами id, text и object:

Query q = mySession.createQuery(
    "SELECT u.id AS id, u.name AS text, u AS object FROM User u")
    .setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP);

... но object кажется зарезервированным словом. Например, obj в порядке. Каков текущий способ избежать псевдонима в HQL, как MySQL использует экранирование от обратной черты?

Использование backtick дает следующую ошибку:

Exception in thread "main" org.hibernate.QueryException: unexpected char: 
'`' [SELECT u.id AS id, u.name AS text, u AS `object` FROM User u]

Ответы [ 4 ]

10 голосов
/ 22 апреля 2011

Вы можете добиться этого путем обходного пути, используя свой собственный преобразователь «псевдоним для сопоставления», поэтому ваш код изменится на что-то вроде этого

Query q = mySession.createQuery(
    "SELECT u.id AS id, u.name AS text, u AS obj FROM User u")
    .setResultTransformer(
        AliasToMapTransformer.renameAlias("obj", "object").build()
    );

И затем с помощью этого класса:

public class AliasToMapTransformer extends BasicTransformerAdapter {

    private Map<String, String> renameAliasMap;


    public AliasToMapTransformer(Map<String, String> renameAliasMap) {
        this.renameAliasMap = (renameAliasMap == null) ? Collections.<String, String>emptyMap() : renameAliasMap;
    }


    @Override
    public Object transformTuple(Object[] tuple, String[] aliases) {
        Map<String, Object> result = new HashMap<String, Object>(tuple.length);
        for (int i = 0; i < tuple.length; i++) {
            String alias = aliases[i];
            if (alias != null) {
                String newAlias = renameAliasMap.get(alias);

                result.put((newAlias != null) ? newAlias : alias, tuple[i]);
            }
        }
        return result;
    }


    public static Builder renameAlias(String alias, String newAlias) {
        return new Builder().renameAlias(alias, newAlias);
    }


    public static class Builder {

        private Map<String, String> aliasConversionMap = new HashMap<String, String>();


        public Builder renameAlias(String alias, String newAlias) {
            aliasConversionMap.put(alias, newAlias);
            return this;
        }


        public AliasToMapTransformer build() {
            return new AliasToMapTransformer(aliasConversionMap);
        }
    }
}
5 голосов
/ 25 октября 2012

В связанной теме экранирование зарезервированного слова в имени столбца так же просто, как добавить псевдоним таблицы. Никаких кавычек, квадратных скобок и т. Д. Просто замените

select where from mytable

по:

select t.where from mytable t

(примечание: я НЕ говорю, что в качестве имени столбца стоит указывать "где"; -)

2 голосов
/ 17 апреля 2011

концепция обратных тиков работает в спящем режиме ... к сожалению, это работает, только если вы выполнили настройку аннотаций ...

вы можете попытаться сделать это по-другому (без аннотаций).

Query q = session.createQuery("select new User (u.id, u.name, u.object) from User u").list();

здесь вам нужно создать используемый конструктор, который принимает id, имя, элементы объекта и в этом порядке.

0 голосов
/ 16 апреля 2011

Бэктики не работают на псевдонимах? Документация Hibernate говорит, что использовать их для полей.

Другие вопросы:

  • Возможно ли другое значение?
  • Почему карта (этотакже содержит оригинальное значение), а не список?Идентификатор и имя могут быть получены из исходного объекта.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...