2011-02-02 22 views
16

Tengo una tabla en Oracle, donde SC_CUR_CODE columna es CHAR (3)Hibernate consulta nativa - char (3) la columna

Cuando hago:

Query q2 = em.createNativeQuery("select sc_cur_code, sc_amount from sector_costs"); 

    q2.setMaxResults(10); 

    List<Object[]> rs2 = q2.getResultList(); 

    for (Object[] o : rs2) { 
     System.out.println(">>> cur=" + o[0]); 
    } 

veo cur=E y cur=U en lugar de cur=EUR y cur=USD

o[0] es una java.lang.Character

¿Cómo puedo conseguir la plena Valu e EUR y USD?

Respuesta

34

Parece que Hibernate lee el valor de tipo CHAR(n) como Character. Tratar de echarlo a VARCHAR(n):

Query q2 = em.createNativeQuery(
    "select cast(sc_cur_code as VARCHAR2(3)), sc_amount from sector_costs"); 

Al utilizar Hibernate a través de Session interfaz, se puede establecer explcitly un tipo de resultado con addScalar() lugar (también accesible a través de unwrap() en JPA 2.0):

Query q2 = em.createNativeQuery(
    "select sc_cur_code, sc_amount from sector_costs"); 
q2.unwrap(SQLQuery.class).addScalar("sc_cur_code", StringType.INSTANCE); 

Hay hay muchos problemas no resueltos relacionados con este problema en Hibernate JIRA, a partir del HHH-2220.

Aquí es una explicación por Max Rydahl Andersen de los comentarios de HHH-2220:

Actualmente Hibernate soporta una especie de mapeo "automagic" de los tipos de SQL a los tipos de Hibernate/Java - a causa de las muchas ambigüedades en hacer tal mapeo, en algún momento no coincidirá con lo que realmente quiere.

Es por eso que siempre recomendamos utilizar addScalar explícito O, si no desea que todo su código utilice la subclase de Dialect para dictar cuál de las múltiples asignaciones posibles desea.

El problema con CHAR es el más problemático, pero no es fácil de arreglar, necesitaríamos un registerType (type, from, to, typename) para mapear un rango en lugar de una longitud específica ... pero incluso entonces podría toparse con ambigüedades de asignación (por ejemplo, alguna vez desea una matriz, etc.). Por lo tanto, se recomienda usar .addScalar para cualquier consulta nativa de sql, dependiendo de la detección automática siempre será arriesgado y solo debe usarse al mínimo.

Si tiene su consulta nativa descrita en el archivo de configuración de mapeos de Hibernate, entonces necesita definir <return-scalar ...> para cada valor devuelto. Nota: debe enumerar todos los valores devueltos, ya que cuando define explícitamente los tipos de devolución, el autodescubrimiento se desactiva y solo se devuelven las columnas declaradas.

<sql-query name="myQuery"> 
    <query-param name="days" type="int" /> 
    <return-scalar column="count" type="int" /> 
    <return-scalar column="section_name" type="string" /> 
    <![CDATA[select count(id) as count, section_name from document where days <= :days]]> 
</sql-query> 
+0

Sí, eso es todo. Encontré el problema según jira para esta función. http://opensource.atlassian.com/projects/hibernate/browse/HHH-2304 – Guus

+0

wonderful explan !!! – lwpro2

+1

tengo una columna como char (10). y obtengo un error cuando intento enviar (... como VARCHAR). funciona bien cuando uso cast (.... como CHAR) – kommradHomer

Cuestiones relacionadas