The Java Persistence Query Language: JPA y la funcion NVL o ISNULL en Oracle

2,881 views
Skip to first unread message

Roxi

unread,
Aug 20, 2008, 7:30:59 PM8/20/08
to JavaSOS
Tengo un problema y he buscado en todas partes y hasta ahora no he
encontrado nada, quisiera saber si alguno me puede ayudar
seria de gran ayuda para mi, sucede que estoy pasando mis consultas de
SQL a JPQL el problema es que en
casi la mayoria utilizo la funncion ISNULL, que en oracle seria
equivalente a NVL, la cuestion es que no se
como simularla en JPA o que utilizar en vez de ISNULL , se agredece la
ayuda a brindar ............

Santiago Risaro

unread,
Aug 21, 2008, 12:06:37 AM8/21/08
to jav...@googlegroups.com
Podés ejecutar la query como si fuera una query nativa de oracle. No es la mejor solución porque perdés el beneficio de la abstracción, pero no conozco otra, por ahora.

Javier Callo Quispe

unread,
Aug 21, 2008, 12:07:32 AM8/21/08
to jav...@googlegroups.com
no tengo mucha experiencia en el manejo de JPA, pero si tengo cierta referencia del tema, pero
no se de que se trata exactamente tu pregunta o tu duda en todo caso puede apelar al metodo,

CreateQuery(Strin jpql) o el metodo CreateNativeQuery(String SQL) de la clase ENTITYMANAGER,
el primero permite especificar sentencia segun el lenguaje JPQL, o en el 2do caso de CreateNativeQuery(String SQL)  , se puede especificar la sentencia SQL nativo.
--
Saludos.

Javier Callo Quispe
----------------------------------------
cell : 991216720

Calabaza

unread,
Aug 20, 2008, 10:40:14 PM8/20/08
to jav...@googlegroups.com
2008/8/20 Roxi <Roxana....@gmail.com>:

Mira: primera vez en mi vida que escucho sobre jpql y jpa, así que me
puse a googlear y encontré esto a ver si te sirve:

[1]http://forums.sun.com/thread.jspa?messageID=10003566

Y lo que le pregunte a google fue:
http://www.google.com.py/search?hl=es&safe=off&q=JPA+jpql+is+null&btnG=Buscar&lr=

Me parece que tiene algo que ver en que parte de la consulta utilizas
esa función, en el where o en el select, podrias dar un ejemplo?

Un abrazo....
--
§~^Calabaza^~§ from Villa Elisa, Paraguay

John Arevalo

unread,
Aug 21, 2008, 9:51:08 AM8/21/08
to jav...@googlegroups.com
2008/8/20 Calabaza <cala...@gmail.com>:
tomado de: http://edocs.bea.com/kodo/docs40/full/html/ejb3_overview_query.html

IS [NOT] NULL: Specifies that the field is equal to null. For example:

SELECT x FROM Magazine x WHERE x.publisher is null

This statement will return all Magazine instances whose "publisher"
field is set to null.


Saludos,
--
John Arévalo
GNU/Linux User #443701
http://counter.li.org/

Roxi

unread,
Aug 21, 2008, 10:48:25 AM8/21/08
to JavaSOS


De antemano muchas gracias a todos , quienes me han ayudado para
encontrar la respuesta. El JPQL "The Java Persistence Query Language"
es el lenguaje para consultas persistentes, el problema que estoy
teniendo es que tengo que pasar mis consultas de SQL a este lenguaje
JPQL y no se como simular en este lenguaje de consultas el
tabla.campo = NVL(?, tabla.campo), el nvl es el que se usa en Oracle y
lo que hace es que si el valor viene nulo, entonces se toma el valor
del segundo argumento, pero si no viene nuelo como este caso
tabla.campo = NVL(2, tabla.campo), se va a traer todos los datos donde
tabla.campo se igual a 2.
para ser mas especifica tengo como ejemplo lo sgte:

Select E from empleados E
where E.codempleado = NVL(null, E.codempleado)

pero esto me produce un error porque no encuentra lo que es NVL,
entonces lo he probado de las sgtes formas:

Select E from empleados E
where E.codempleado = Is Null (null, E.codempleado)

Pero no me ha funciona hasta ahora, les agradezco de antemano la ayuda
que me puedan brindar =)

Calabaza

unread,
Aug 20, 2008, 10:46:30 PM8/20/08
to jav...@googlegroups.com
2008/8/20 Calabaza <cala...@gmail.com>:

Mira también esto, a lo mejor te sirve:
[2]http://edocs.bea.com/kodo/docs40/full/html/ejb3_langref.html#ejb3_langref_null

John Arevalo

unread,
Aug 21, 2008, 11:25:47 AM8/21/08
to jav...@googlegroups.com
2008/8/20 Calabaza <cala...@gmail.com>:
En la documentación oficial de la EJBQL[1] parece que no existe aún
una función o palabra reservada que haga condicionales dentro de los
campos seleccionados :(

Podrías generar la consulta nativa, y hacer un mapping a la consulta
para que esta devuelva uno o mas objetos de tus Entity Classes.
puedes ver un ejemplo de los mapping aqui[2]


[1] http://java.sun.com/javaee/5/docs/tutorial/doc/bnbuf.html
[2] http://www.oracle.com/technology/products/ias/toplink/jpa/resources/toplink-jpa-annotations.html#SqlResultSetMapping

Hugo Arregui

unread,
Aug 21, 2008, 11:47:19 AM8/21/08
to jav...@googlegroups.com
tal vez JPQL no defina un NVL.. (solo lo he visto en oracle)

podrias hacer algo como:

Select E from empleados E

where E.codempleado = 2 OR E.codempleado is null

Depende donde lo estes usando.

Saludos

Hugo.

2008/8/21 John Arevalo <johna...@gmail.com>:

Roxi

unread,
Aug 21, 2008, 1:18:11 PM8/21/08
to JavaSOS

Si me parece muy buena solucion, Si no fuera que o que viene por
argumento fuera un null, porque generarlmente cuando es null
NVL(null,tabla.campo) se toma esntonces el segundo argumento. y cuando
se ejecutan estas consultas y no viene nada se manda la palabra null,
la cual la entiende oracle y toma el valor del segundo argumento .,
gueno cualquiera diria no mandes null, manda otras cosas , pero he ahi
el detalle son todas las consultas de un sistema que se hizo para
ejecutar sus consultas en Oracle y cambiarlos no resulta tan sencillo
=P.. Gracias por tu respuesta

entonces tendria como resultado la sgte consulta.

Select E from empleados E
where E.codempleado = null OR E.codempleado is null

lo cual la heramienta JPA Query TooL me tira el sgte error:

unexpected token [null].
Internal Exception: line 1:51: unexpected token: null

Roxi

unread,
Aug 21, 2008, 1:18:32 PM8/21/08
to JavaSOS

Si me parece muy buena solucion, Si no fuera que o que viene por
argumento fuera un null, porque generarlmente cuando es null
NVL(null,tabla.campo) se toma esntonces el segundo argumento. y cuando
se ejecutan estas consultas y no viene nada se manda la palabra null,
la cual la entiende oracle y toma el valor del segundo argumento .,
gueno cualquiera diria no mandes null, manda otras cosas , pero he ahi
el detalle son todas las consultas de un sistema que se hizo para
ejecutar sus consultas en Oracle y cambiarlos no resulta tan sencillo
=P.. Gracias por tu respuesta

entonces tendria como resultado la sgte consulta.

Select E from empleados E

Roxi

unread,
Aug 21, 2008, 1:18:54 PM8/21/08
to JavaSOS

Hugo Arregui

unread,
Aug 21, 2008, 1:34:16 PM8/21/08
to jav...@googlegroups.com
en realidad, queria mostrarte como reemplazar el NVL, no digo q la
sintaxis q puse sea correcta (me acabo de enterar q existe JPA).

Pero,


Select E from empleados E
where E.codempleado = null OR E.codempleado is null

estas poniendo lo mismo de ambos lados, el = null -aparentemente- se
reemplaza por IS NULL.

Saludos.


2008/8/21 Roxi <Roxana....@gmail.com>:

Pablo Molnar

unread,
Aug 21, 2008, 2:22:34 PM8/21/08
to jav...@googlegroups.com
NVL es una funcion especifica de Oracle.
JPA es un estandar cross a diferentes frameworks de persistencia y bases de datos por lo que no va a tener una funcion de oracle.

Lo que podes hacer es usar SQL puro con CreateNativeQuery para utilizar NVL.

Slds
Pablo

Roxi

unread,
Aug 21, 2008, 2:51:04 PM8/21/08
to JavaSOS
Si yo te entiendo , y te agradezco mucho tu ayuda =)
Si tambien lo probe asi
select u from Segusuario u
where u.conusuario = null or u.conusuario is null, pero la herrmienta
q utilizo no me permite la palabra null.

Siembargo me diste algo por lo que puedo intentar saludes y muchas
Gracias......

Hugo Arregui

unread,
Aug 21, 2008, 2:53:10 PM8/21/08
to jav...@googlegroups.com
mmm... no se si te estoy entendiendo mal, pero me parece q el = null
deberias sacarlo.

2008/8/21 Roxi <Roxana....@gmail.com>:

Roxi

unread,
Aug 21, 2008, 4:05:56 PM8/21/08
to JavaSOS

Muy agradecida de verdad por su colaboracion, yo se que puedo utilizar
consultas nativas, pero la idea es pasar las consultas nativas de
oracle a JPQL con la herramienta para consultas "JPA Query Tool",
que es una heramienta que encontre para ejecutar consultas utilizando
The Java Persistence Query Language y sus estandares , la idea es no
depender de una base datos Oracle o SQL, si no de este tipo de
lenguaje que sea independiente de la base de datos . El problema
radica en tratar de simular el NVL en JPQL
ya que como bien lo dice Pablo Molnar : JPA es un estandar cross a
diferentes frameworks de persistencia y bases de datos por lo que no
va a tener una funcion de oracle. Pero trato de encontrar alguna
forma..., alguna otra idea es bien recibida Gracias

John Arevalo

unread,
Aug 21, 2008, 5:54:07 PM8/21/08
to jav...@googlegroups.com
2008/8/21 Roxi <Roxana....@gmail.com>:
A mi modo de ver... JPA aun no logra cubrir todas las necesidades de
las consultas, facilita algunas cosas, pero en ciertos casos es
necesario el uso de queries nativas, como una consulta crosstab[1] o
pivot(en access).

"It is not recommended that you use a SQL keyword as an identifier,
because the list of keywords may expand to include other reserved SQL
words in the future."[2] , esto nos indica que JPA aún no tiene
implementadas todas las herramientas de consulta SQL.

Para tu caso, y como dije en un post anterior, al parecer la sintaxis
de JPA no soporta condicionales en la selección de campos. Usa un
mapping en una consulta nativa si quieres que retorne Objetos Java


Saludos,


[1] http://www.orafaq.com/wiki/SQL_FAQ#How_does_one_code_a_matrix.2Fcrosstab.2Fpivot_report_in_SQL.3F
[2] http://java.sun.com/javaee/5/docs/tutorial/doc/bnbuf.html#bnbuk

Pablo Molnar

unread,
Aug 21, 2008, 6:16:09 PM8/21/08
to jav...@googlegroups.com
Si estas usando HQL y el dialecto org.hibernate.dialect.Oracle9Dialect te va aceptar nvl() ya que si ves en el código fuente [1] se implementa la función. Igualmente con esto salís del estándar de JPQL.

Slds!
Pablo

2008/8/21 Roxi <Roxana....@gmail.com>

Calabaza

unread,
Aug 22, 2008, 2:15:44 AM8/22/08
to jav...@googlegroups.com
2008/8/21 Roxi <Roxana....@gmail.com>:

> el problema que estoy
> teniendo es que tengo que pasar mis consultas de SQL a este lenguaje
> JPQL y no se como simular en este lenguaje de consultas el
> tabla.campo = NVL(?, tabla.campo), el nvl es el que se usa en Oracle y

> lo que hace es que si el valor viene nulo, entonces se toma el valor


> del segundo argumento, pero si no viene nuelo como este caso
> tabla.campo = NVL(2, tabla.campo), se va a traer todos los datos donde
> tabla.campo se igual a 2.
> para ser mas especifica tengo como ejemplo lo sgte:

> Select E from empleados E
> where E.codempleado = NVL(null, E.codempleado)

Hagamos esto con datos a ver que necesitas que devuelva:

Empleados
codempleado - nombre
1 - aaaaa
2 - bbbbb
3 - ccccc
4 - ddddd

Según esta consulta qué debe devolver cuando e.codeempleado es null?:

> Select E from empleados E

> where E.codempleado = NVL(null, E.codempleado)

asi como esta escrito debe devolver:
Error...

Corrigiendo tu consulta, quizás quedaría así?:
> Select E.* from empleados E
> where E.codempleado = NVL(E.codempleado, E.codempleado)

Corregí de esta forma tu consulta porque he buscado ayuda sobre la
sintaxis de nvl() y he visto aqui[1] y aqui también[2]
[1]http://www.techonthenet.com/oracle/functions/nvl.php
[2]http://download.oracle.com/docs/cd/B28359_01/olap.111/b28126/dml_functions_2048.htm

Que dice:

[1]"In Oracle/PLSQL, the NVL function lets you substitute a value when
a null value is encountered.
The syntax for the NVL function is:
NVL( string1, replace_with )
string1 is the string to test for a null value.
replace_with is the value returned if string1 is null."

En Oracle/PLSQL, la función NVL le permite a Ud sustituir un valor
cuando se encuentra un valor de null.

La sintaxis para la función NVL es:
NVL(cadena1, reemplazar_con )
cadena1 es la cadena que se evaluará para ver si es un valor null.
reemplazar_con es el valor a ser retornado si cadena1 es null.

O sea que estas mal utilizando la funcion nvl() o copiaste mal el
ejemplo, si puedes ser más precisa te lo agradeceríamos.

> pero esto me produce un error porque no encuentra lo que es NVL,
> entonces lo he probado de las sgtes formas:

> Select E from empleados E
> where E.codempleado = Is Null (null, E.codempleado)
y aquí posiblemente si la idea es legar a comparar E.codempleado =
E.codempleado te daría otro error que puedes ir mirando en:
[3]http://forums.oracle.com/forums/message.jspa?messageID=2632098

Y también hay sobre lo que algunos ya te dijeron:
[4]http://forums.oracle.com/forums/thread.jspa?threadID=695515&tstart=0

El día 21 de agosto de 2008 11:47, Hugo Arregui
<hugo.a...@gmail.com> escribió:


> tal vez JPQL no defina un NVL.. (solo lo he visto en oracle)
>
> podrias hacer algo como:
>

> Select E from empleados E

> where E.codempleado = 2 OR E.codempleado is null
>
> Depende donde lo estes usando.
>
> Saludos
>
> Hugo.


El 2008/8/21 Roxi <Roxana....@gmail.com>:

> Si me parece muy buena solucion, Si no fuera que o que viene por
> argumento fuera un null, porque generarlmente cuando es null
> NVL(null,tabla.campo)
> se toma esntonces el segundo argumento. y cuando
> se ejecutan estas consultas y no viene nada se manda la palabra null,
> la cual la entiende oracle y toma el valor del segundo argumento .,

bueno, aquí ya no te entiendo, podrías hacer mención cuando es un valor null?
y cual es el nombre de la variable de la cadena que es evaluada con el nvl()?

> gueno cualquiera diria no mandes null, manda otras cosas , pero he ahi
> el detalle son todas las consultas de un sistema que se hizo para
> ejecutar sus consultas en Oracle y cambiarlos no resulta tan sencillo
> =P.. Gracias por tu respuesta

> entonces tendria como resultado la sgte consulta.

> Select E from empleados E
> where E.codempleado = null OR E.codempleado is null

> lo cual la heramienta JPA Query TooL me tira el sgte error:
> unexpected token [null].
> Internal Exception: line 1:51: unexpected token: null

La descripción del error te dice que no se esperaba el token (palabra
reservada?) null porque imagino que necesita el nombre de una variable
para utilizarla con el operador =

Creo que "traduciste mal" el comportamiento de la funcion NVL()

Mira esto:

Select E.* from empleados E
where E.codempleado = tu_variable OR E.codempleado is null

Esto es lo mismo que te dijo Hugo en su respuesta....

Amigos: este es el hilo mas difícil de seguir de mi vida, a ver si me ubico....
(recién reviso el correo) (les sugeriría utilizar algunas normas
básicas como no al top posting y dejar todos los mensajes al
responder, a fin de que el que lee pueda ubicarse con solo leer el
ultimo mensaje, pero es solo una sugerencia, ya estoy muy mareado de
revisar tanto toda la conversación ;)

Roxi: disculpas si no soy tan claro. :)

A todos un abrazo.

Roxi

unread,
Aug 22, 2008, 6:39:08 PM8/22/08
to JavaSOS


Les agradezco a todos por su colaboracion, en realidad este es grupo
es muy bueno, las ayudas son inmediatas , y son personas con mucho
conocimiento, sobretodo agradecer a Hugo Arregi quien me dio una
solucion muy buena , incialmente no la pude utilizar porque mi
herramienta no entiende la palabra reservada null, null es lo que le
llega para decirle en el caso del nvl que se traiga todos los datos,
pero en fin, la herramienta que utilizo "JPA Query Tool" es solo para
probar las consultas en realidad la prueba final va a ser al probar el
sistema. Gueno asi implemente la simulacion del NVL en el lenguaje
JPQL:

select u from usuarios u LEFT JOIN u.historialclaves hc
where (hc.codclave = ? or ? is null)

La prueba final, sera al correr el sistema. Pero ahi les cuento como
me va

Roxi

unread,
Aug 22, 2008, 6:44:12 PM8/22/08
to JavaSOS


On 22 ago, 00:15, Calabaza <calali...@gmail.com> wrote:
> 2008/8/21 Roxi <Roxana.Riet...@gmail.com>:
> [2]http://download.oracle.com/docs/cd/B28359_01/olap.111/b28126/dml_func...
> <hugo.arre...@gmail.com> escribió:
>
> > tal vez JPQL no defina un NVL.. (solo lo he visto en oracle)
>
> > podrias hacer algo como:
>
> > Select E from empleados E
> > where E.codempleado = 2 OR  E.codempleado is null
>
> > Depende donde lo estes usando.
>
> > Saludos
>
> > Hugo.
>
> El 2008/8/21 Roxi <Roxana.Riet...@gmail.com>:
En cuanto a lo del hilo mas dificil tienes toda la razon , hasta a mi
me cuesta ubicarme . jejejeje
seguiere tu recomendacion gracias

Roxi

unread,
Aug 22, 2008, 7:07:25 PM8/22/08
to JavaSOS
> seguiere tu recomendacion gracias- Ocultar texto de la cita -
>
>
Ahora si te voy a contestar cada una de las preguntas
1) Según esta consulta qué debe devolver cuando e.codeempleado es
null?:
R/Deveria devolver
> > 1 - aaaaa
> > 2 - bbbbb
> > 3 - ccccc
> > 4 - ddddd
2)bueno, aquí ya no te entiendo, podrías hacer mención cuando es un
valor null?
> > y cual es el nombre de la variable de la cadena que es evaluada con el nvl()?
R/select u from usuarios u LEFT JOIN u.historialclaves hc
where (hc.codclave = ? or ? is null)
Los son ? parametros usados, que ese parametro puede venir con el
valor de null quedando asi
select u from usuarios u LEFT JOIN u.historialclaves hc
where (hc.codclave = null or null is null)
pero si trae un valor queda asi:
select u from usuarios u LEFT JOIN u.historialclaves hc
where (hc.codclave = 'micalve' or 'miclave' is null)

Esta es mi primera vez en un grupo, se aprende mucho de
verdad...........



as1

unread,
Aug 22, 2008, 10:09:14 PM8/22/08
to JavaSOS
Una solucion seria que hagas una vista que te elimina la necesidad de
usar NVL. La otra es una Toplink mediante JPA que al ser de Oracle
debe solucionar este tema.

YeSSa

unread,
Aug 23, 2008, 12:01:00 PM8/23/08
to JavaSOS
Desconozco esa funcion NVL, pero si lo que necesitas es usar la
funcion null con JPA te dejo esto,

@NamedQueries(
{
@NamedQuery(name="getLevelValuesCountry", query = "SELECT levelValue
FROM LevelValue levelValue " +
" WHERE levelValue.levelAddress.levelAddressId = :levelAddressId "
+
" AND levelValue.levelValueParent IS NULL ")
}
)


Para hacer llamado al query solo debes hacer esto:
@PersistenceContext private EntityManager manager;

Query query = manager.createNamedQuery("getLevelValuesCountry");
query.setParameter("levelAddressId", idLevelAddress);

Santiago Risaro

unread,
Aug 23, 2008, 8:15:58 PM8/23/08
to jav...@googlegroups.com
Lo de la vista puede ser una buena solución.

Si usa JPA puro con toplink no soluciona el problema, porque JPA es una abstracción sobre los ORM, por lo tanto uno no sabe cual está usando, no importa que sea hibernate (que también soporta NVL) o TopLink.

¿JPQL soporta "CASE ... WHEN... "? con eso podés hacer tu propio NVL
Reply all
Reply to author
Forward
0 new messages