Investigué un poco, pero aún no tengo una respuesta satisfactoria. Tengo una tabla, y se supone que tiene 3 registros si la ejecuto bajo un sistema de administración de base de datos como navicat.
____ id | ____ 1 | 2 | 3 |Si uso el parámetro establecido con una cadena concatenada, devolverá solo el primer valor
List<Integer> here = Arrays.asList(new Integer[]{1, 2, 3}); SQLQuery query = session.createSQLQuery("SELECT * FROM table WHERE id IN (:here)"); query.setParameter("here", StringUtils.join(here, ",")); query.setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP); query.list(); pero si uso setParameterList , devolverá todos los valores:
List<Integer> here = Arrays.asList(new Integer[]{1, 2, 3}); SQLQuery query = session.createSQLQuery("SELECT * FROM table WHERE id IN (:here)"); query.setParameterList("here", here ); query.setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP); query.list();Lo depuré para ver el sql real, pero no veo ningún problema en el primer caso
Hibernate: /* dynamic native SQL query */ SELECT * FROM table WHERE id IN ( ? ) HibernateLog --> TRACE org.hibernate.type.descriptor.sql.BasicBinder - binding parameter [1] as [VARCHAR] - [1,2,3] TRACE BasicBinder:81 - binding parameter [1] as [VARCHAR] - [1,2,3]¿Alguien puede explicar profundamente por qué el primer caso no funciona? Estoy usando mysql.
EDITAR:
Gracias por todas las sugerencias. Después de usar log4jdbc-log4j2-jdbc4.1 y cerrar la sesión de sql (antes de que hibernate lo envíe a la base de datos):
DEBUG jdbc.sqlonly - com.mchange.v2.c3p0.impl.NewProxyPreparedStatement.executeQuery(NewProxyPreparedStatement.java:116) 500. SELECT * FROM table WHERE id IN ('1,2,3') 16:19:33.518 [http-nio-8280-exec-4] INFO jdbc.resultsettable - |---| |id | |---| |1 | |---|Cualquiera que quiera registrar el sql completo antes de que vaya a la base de datos puede ver este enlace: https://stackoverflow.com/a/19299769/4181109
Parece que la causa principal de este comportamiento es la conversión de tipos de MySql en la evaluación de expresiones .
MySql intenta convertir pasado al expr IN (value,...) '1,2,3' al tipo DOUBLE (ver esto ) y como resultado obtienes:
SELECT * FROM table WHERE id IN (1)cuando ejecutas esto:
SELECT * FROM table WHERE id IN ('1,2,3')y mysql también generan la siguiente advertencia:
Warning: Truncated incorrect DOUBLE value: '1,2,3'Eso es de esperar ya que hibernate está detectando tipos para construir su consulta y envía una cadena en lugar de una lista. El segundo método le dice explícitamente que espere una lista.