2010-08-16 18 views
6

Hola chicos, estoy teniendo algunos problemas con las coincidencias exactas mientras hago un NamedQuery.JAVA: NamedQuery String problema

actualmente estoy usando algo como esto:

@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()); 

Funciona para la mayoría de los casos, sin embargo me di cuenta de que, en caso de que el usuario pase el nombre del archivo con un espacio al final, la namedQuery hace caso omiso de ese personaje. Por ejemplo:

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

Devolverá el mismo resultado que la consulta anterior. Pasando por alto mi validación de 'entrada válida'. En otras palabras, me gustaría que la consulta no devuelva ninguna entrada y trate el error más adelante.

Una solución que podía pensar, es poner comillas simples que rodean mi parámetro en el namedQuery, así:

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

Sin embargo, será la basura mi código en caso de que la cadena contiene comillas simples en ella ..

¿Alguna idea, chicos?

Respuesta

4

me hizo una investigación en la APP y descubrió que lo hace un poco de recorte automático para CHAR, me no estoy seguro de si esto se comporta de la misma manera con Strings, pero como me está sucediendo a mí ... eso creo. La única forma de eludirlo es mediante la configuración de algún atributo dentro del objeto DatabaseLogin de la sesión (consulte http://www.eclipse.org/eclipselink/api/1.1/org/eclipse/persistence/sessions/DatabaseLogin.html#setShouldTrimStrings).

Bueno, no quería estropear las propiedades de la sesión, así que decidí hacer algún tipo de comprobación y arrojar la misma excepción que la captura NoResultException en mi código.

básicamente tomó el resultado de la base de datos y compara el campo con la cadena utilicé:

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

... 

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

También he tenido que incluir la función Trim axtavt! Esto es solo para asegurarse de que si la base de datos tiene una columna con espacios finales y coincide con el parámetro proporcionado por el usuario, se incluirá como una respuesta válida. Por ejemplo:

Entrada de la base de datos: Name = "Flavio" - Recortada con la función = "Flavio".

parámetro pasado: Name = "Flavio" - Recortado por APP función automática = "Flavio".

Si isnt recortado en absoluto se acaba de comparación "Flavio" con "Flavio", volviendo noresult cuando se supone que devuelve esa entrada.

solución desagradable, pero siempre y cuando no hay otra manera de detener el auto-recorte tendremos que acaba de hacer uso de este tipo de cosas.

¡Gracias por todas las otras respuestas!

4

Supongo que esto sucede porque su campo de base de datos está declarado como CHAR(...), y por lo tanto los valores almacenados se rellenan con espacios en blanco que no se tienen en cuenta por el funcionamiento =.

Por lo tanto, es posible que sea declarar su campo de base de datos como VARCHAR(...) o utilizar un sistema incorporado en trim función:

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

Hola axtavt, gracias por la rapidez en la respuesta! Bueno, mi base de datos está configurada en VARCHAR. Pero no estoy seguro si la versión de MySql tiene algo que ver con este problema. También pensé en hacer algunos ajustes antes de establecer el parámetro para la consulta, sin embargo, quería que el software devolviera el error por cualquier cosa que fuera diferente de la base de datos, asegurando que el usuario ingresa exactamente lo que quería. –

+0

@flavio: No estoy familiarizado con MySQL, por lo que no puedo decir nada sobre sus características. También tenga en cuenta que mi muestra de consulta recorta el valor almacenado, no el parámetro, por lo que el resultado debe ser exacto. – axtavt

+0

Depuré el código comprobando el proceso de creación de la consulta ... Con el código proporcionado, parece que el problema está en mySql. Noté que ambos parámetros y la entrada de la base de datos SON diferentes ... sin embargo, para una fuerza divina mística desconocida, MySql simplemente recorta los espacios y considera que coincide exactamente ... Ahora creo que tengo que hacer algunas investigaciones para ver si esto es así. realmente un comportamiento esperado de MySql o hay algo más detrás de esto. Por el momento, creo que tendré que hacer algún tipo de controles adicionales. ¡Gracias! –