JAVA:NamedQuery String问题

时间:2010-08-16 15:00:57

标签: java jpa jpql named-query

大家好,我在做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 个答案:

答案 0 :(得分:4)

我想这是因为你的数据库字段被声明为CHAR(...),因此存储的值用空格填充,=操作不考虑这些空格。

因此,您可以将数据库字段声明为VARCHAR(...)或使用内置trim函数:

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

答案 1 :(得分:4)

我在JPA做了一些研究,发现它为CHARs做了一些自动修剪,我不确定这与Strings的行为是否相同,但是因为它发生在我身上......我相信如此。绕过它的唯一方法是在会话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” - 使用Function =“Flavio”修剪。

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

如果它没有被修剪,它只会比较“Flavio”和“Flavio”,当它应该返回该条目时返回NoResult。

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

感谢所有其他答案!!