2010-03-15 41 views
17

¿Hay alguna manera de especificar parámetros opcionales (como cuando se proporcionan los parámetros de búsqueda desde un formulario y no se requieren todos los parámetros) en una consulta con nombre cuando se utiliza Hibernate? Estoy usando una consulta SQL nativa, pero la pregunta probablemente también sea aplicable a consultas HQL con nombre.Parámetros opcionales con consulta con nombre en Hibernate?

Estoy bastante seguro de que la respuesta es 'no', pero todavía no encontré la respuesta definitiva en la documentación.

Respuesta

10

AFAIK, no hay tal cosa así que tendrás que escribir una consulta dinámica para esto. Tal vez eche un vistazo a este previous answer que muestra cómo hacerlo en HQL (que puede transponer a SQL) y también muestra cómo la API Criteria lo hace más simple y, por lo tanto, es más adecuado para este trabajo en mi opinión.

Actualización: (respondiendo a un comentario de la OP) Trabajar con una base de datos heredada puede ser complicado con Hibernate. Quizás puedas usar una consulta nativa dinámica y devolver non-managed entities. Pero a la larga, las cosas podrían empeorar (no puedo decir eso por ti). Quizás Hibernate no sea la mejor opción en su caso y algo como iBATIS le daría la flexibilidad que necesita.

+0

Gracias. Eso es más o menos lo que pensé. Estoy familiarizado con los dos enfoques que sugirió en su otra respuesta, pero estoy atrapado con un esquema db de legado de pesadilla que simplemente no es adecuado para el enfoque de Hibernate para mi caso particular. Lo he hecho funcionar hasta el momento, pero tengo algunos requisitos nuevos que parece que no puedo cumplir con el mapeo directo de Hibernate. Probablemente voy a darme por vencido y usar iBATIS para este caso.No es muy emocionante agregar otra tecnología a la pila como una curita, pero así es la vida, supongo. Gracias. – Ickster

+0

@Ickster Vea mi actualización. –

+1

Gracias por la actualización. He considerado ese enfoque también y dada la cantidad de parámetros con los que estoy lidiando, decidí que probablemente sea más limpio usar iBATIS. Gracias por el consejo. – Ickster

29

Como se mencionó en un different answer a la question referenciado anteriormente, el siguiente HQL construcción de obras para mí:

select o from Product o WHERE :value is null or o.category = :value 

si: valor se pasa como nula, se devuelven todos los productos.

Ver también Optional or Null Parameters

Tenga en cuenta que esto no funcionará en algunas versiones de Sybase debido a this bug, por lo que la siguiente es una alternativa:

select o from Product o WHERE isnull(:value, 1) = 1 or o.category = :value 
5

lamentablemente la solución bajo "Parámetros opcionales o nulos "no funciona para listas IN. tuve que cambiar la consulta como sigue ...

Named definición de la consulta:

select ls from KiCOHeader co 
... 
join lu.handlingType ht 
where (:inHandlingTypesX = 1 OR ht.name in (:inHandlingTypes)) 

Código:

Set<KiHandlingTypeEnum> inHandlingTypes = ... 

Query query = persistence.getEm().createNamedQuery("NAMED_QUERY"); 
query.setParameter("inHandlingTypesX", (inHandlingTypes == null) ? 1 : 0); 
query.setParameter("inHandlingTypes", inHandlingTypes); 

List<KiLogicalStock> stocks = query.getResultList(); 

Mucha diversión de trabajo.

+0

que ya no funciona ... – george

2

Otra solución para manejar los parámetros de lista opcionales es mediante la comprobación de nulo mediante la función COALESCE. COALESCE es supported by Hibernate devuelve el primer parámetro no nulo de una lista, lo que le permite comprobar nulo en una lista sin romper la sintaxis cuando hay varios elementos en la lista.

ejemplo HQL con el parámetro de parámetros y lista opcional:

select obj from MyEntity obj 
where (COALESCE(null, :listParameter) is null or obj.field1 in (:listParameter)) 
    and (:parameter is null or obj.field2 = :parameter) 

Esto funcionó para mí con un dialecto de SQL Server.

+0

Esto no funcionó, hibernate se quejó de 'COALESCE (null,)' cuando ': listParameter' no estaba definido. Mi solución también fue pasar un parámetro adicional y tener la condición where escrita de esta manera: '(: listParamterSize = 0 u obj.field1 en (: listParameter))' – jeremija

+0

Funciona, pero ': listParameter' debe definirse, al menos como nulo. La ventaja de esta solución es que puede pasar el parámetro como nulo y no es necesario el parámetro adicional. –

Cuestiones relacionadas