6

大家好,我在执行 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 "'")

但是,如果字符串中包含单引号,它将破坏我的代码...

有什么想法吗?

4

2 回答 2

4

I guess this happens because your database field is declared as CHAR(...), and therefore stored values are padded with whitespaces which are not taken into account by = operation.

So, you may either declare your database field as VARCHAR(...) or use a built-in trim function:

query = "select e from Entry e where trim(trailing from e.name) =:"+ Entry.NAME
于 2010-08-16T15:26:45.367 回答
4

我在 JPA 中做了一些研究,发现它对 CHAR 进行了一些自动修剪,我不确定这是否与字符串相同,但因为它发生在我身上......我相信是的。绕过它的唯一方法是在会话 DatabaseLogin 对象中设置一些属性(请参阅http://www.eclipse.org/eclipselink/api/1.1/org/eclipse/persistence/sessions/DatabaseLogin.html#setShouldTrimStrings)。

好吧,我不想弄乱会话属性,所以我决定进行某种检查并抛出与 NoResultException catch 在我的代码中所做的相同的异常。

我基本上从数据库中获取了结果,并将该字段与我使用的字符串进行了比较:

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

...

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

我还必须包括修剪功能 axtavt!这只是为了确保如果数据库有一个带有尾随空格的列并且它与用户给出的参数匹配,它将作为有效答案包含在内。例如:

数据库条目:名称 = "Flavio" - 使用函数 = "Flavio" 修剪。

传递的参数:名称 = “Flavio” - 由 JPA 自动功能修剪 = “Flavio”。

如果它根本没有修剪,它只会将“Flavio”与“Flavio”进行比较,当它应该返回该条目时返回 NoResult。

令人讨厌的解决方法,但只要没有其他方法可以停止自动修剪,我们将不得不使用这种东西。

感谢所有其他答案!

于 2010-08-16T19:05:16.967 回答