JAVA: проблема строки NamedQuery

Привет, ребята, у меня возникли проблемы с точными матчами при выполнении NamedQuery.

В настоящее время я использую что-то вроде этого:

@NamedQuery(name = MyClass.GET_ENTRY_BY_NAME, query = "select e from Entry e where e.name =:"+ Entry.NAME )

...

Query query = em.createNamedQuery(MyClass.GET_ENTRY_BY_NAME);
        query.setParameter(Entry.NAME, myEntry.getName());

он работает в большинстве случаев, однако я заметил, что в случае, если пользователь передает имя файла с пробелом в конце, namedQuery игнорирует этот символ. Например:

Query query = em.createNamedQuery(MyClass.GET_ENTRY_BY_NAME);
        query.setParameter(Entry.NAME, myEntry.getName()+ " ");

вернет тот же результат, что и запрос раньше. Обход проверки "действительной записи". Другими словами, Я хотел бы, чтобы запрос не возвращайте запись вообще и обработайте ошибку позже.

один обходной путь, который я мог бы придумать, - это поставить одинарные кавычки вокруг моего параметра в namedQuery, например:

@NamedQuery(name = MyClass.GET_ENTRY_BY_NAME, query = "select e from entry e where e.name =':"+ Entry.NAME "'")
это будет халтура мой код в случае, если строка содержит одинарные кавычки в нем...

есть идеи, ребята?

2 ответов


Я думаю, это происходит потому, что поле базы данных объявлен как CHAR(...), и поэтому сохраненные значения заполняются пробелами, которые не учитываются = операции.

Итак, вы можете либо объявить поле базы данных, как VARCHAR(...) или использовать встроенный trim функция:

query = "select e from Entry e where trim(trailing from e.name) =:"+ Entry.NAME

Я провел некоторое исследование в JPA и обнаружил, что он делает автоматическую обрезку для символов, я не уверен, что это ведет себя так же со строками, но так как это происходит со мной... Думаю, да. Единственный способ обойти его-установить некоторый атрибут в объекте DatabaseLogin сеанса (см. http://www.eclipse.org/eclipselink/api/1.1/org/eclipse/persistence/sessions/DatabaseLogin.html#setShouldTrimStrings) .

Ну, я не хотел связываться с свойства сеанса, поэтому я решил сделать какую-то проверку и выбросить то же исключение, что и улов NoResultException в моем коде.

Я в основном взял результат из базы данных и сравнил поле со строкой, которую я использовал:

query.setParameter(Entry.NAME, myEntry.getName());

...

if(!StringUtils.equals(result.getName(), myEntry.getName()){
   do a cool throw just like NoResultException Catch
}

мне также пришлось включить функцию обрезки axtavt! Это просто чтобы убедиться, что если в базе данных есть столбец с конечными пробелами и она соответствует параметром, заданным пользователем, он будет включен в качестве ответа. Для пример:

запись в базе данных: Name = "Flavio" - обрезается функцией = "Flavio".

передан параметр: Name = "Flavio" - обрезается автоматической функцией JPA = "Flavio".

если он вообще не обрезается, он просто сравнивает " Flavio "с" Flavio", возвращая NoResult, когда он должен был вернуть эту запись.

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

Спасибо за все остальные ответы!!