2011-07-24 41 views
11

Estoy tratando de ejecutar una consulta que comprueba si algunas condiciones son verdaderas y devuelve un resultado booleano simple como resultado. Lo que lo hace un poco complicado es que una de las condiciones es comprobar si no se devuelven resultados para un conjunto de criterios.¿Es posible seleccionar EXISTS() en JPQL?

Actualmente estoy usando JPA-2.0 con Hibernate como el profesional, el respaldo de MySQL. Obtuve una consulta de ejemplo que funciona bien en MySQL, pero cuando intento ejecutarlo en JPQL falla. La consulta de MySQL se ve un poco como esto:

Select exists(Select statement with criteria) 
    or not exists(Select statement with criteria); 

También me dio el mismo resultado utilizando CASO, sino como JPQL no soporta esa declaración.

De todas formas, cuando trato de utilizar una consulta similar en JPQL me sale el error:

"unexpected end of subtree"

que desde mi comprensión significa que algo falta en la consulta. ¿Alguien tiene alguna idea de cómo solucionarlo?

Respuesta

6

No, no es posible.

Consulte la documentación de Oracle JPQL BNF.

simple_cond_expression ::= comparison_expression | between_expression | like_expression | in_expression | null_comparison_expression | empty_collection_comparison_expression | collection_member_expression | exists_expression

exists_expression ::= [NOT] EXISTS(subquery)

1

Usted tienen soportes que no coinciden. Prueba a eliminar la anterior a la not (y los alrededores de la primera existe):

select exists(Select statement with criteria) 
    or not exists(Select statement with criteria); 

No es necesario corchetes exists()

+1

Gracias por señalarlo, pero la frase "corchetes" o "no" aún no funciona en JPQL. – Elk

+0

http://openjpa.apache.org/builds/1.2.0/apache-openjpa-1.2.0/docs/manual/jpa_langref.html#jpa_langref_exists Así que de acuerdo a la documentación, al menos, existe parte es correcta a partir de la pregunta. "exists_expression :: = [NOT] EXISTS (subconsulta)" – Kowser

1

Como alternativa se puede utilizar un select count(...) y comprobar si vuelve 0. Esto debería ser casi tan eficiente sin requerir escribir mucho más código (de hecho, la consulta en sí misma probablemente parezca más simple).

+1

No necesariamente. 'exists (...)' probablemente existirá después de encontrar el primer resultado. 'count (...)' tendrá que escanear muchas más filas de índice/tabla para determinar el recuento real. –

+0

@KonradGarus: en realidad, no importa, cuando 'count (..)' es la única solución que funcionará en JPQL de todos modos. Entonces, cuando la vida te da limones ... –

4

se puede hacer una consulta booleana utilizando un case expression.

A partir de JPA 2.0 (Java EE 6) se puede create a TypedQuery.

String query = "select case when (count(*) > 0) then true else false end from ......" 
TypedQuery<Boolean> booleanQuery = entityManager.createQuery(query, Boolean.class); 
boolean exists = booleanQuery.getSingleResult(); 

En JPA 1.0 (Java EE 5) se debe utilizar una consulta sin tipo.

Query booleanQuery = entityManager.createQuery(query); 
boolean exists = (Boolean) booleanQuery.getSingleResult(); 
1

En un proyecto que utiliza

<dependency> 
     <groupId>org.hibernate</groupId> 
     <artifactId>hibernate-core</artifactId> 
     <version>4.2.4.Final</version> 
    </dependency> 
    ... 

he usado con éxito una cláusula

exists(select s.primaryKey from Something s) 

. Por lo tanto, podría haber cambiado. También podría ser propiedad de Hibernate. Dado que muchas personas usan Hibernate como proveedor de persistencia, pensé que podría agregar esto aquí.

Cuestiones relacionadas