2011-02-02 17 views
16

Ho una tabella in Oracle dove la colonna SC_CUR_CODE è CHAR (3)Hibernate interrogazione nativa - char (3) colonna

Quando faccio:

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]); 
    } 

vedo cur=E e cur=U invece di cur=EUR e cur=USD

o[0] è un java.lang.Character

Come posso ottenere il pieno valu e EUR e USD?

risposta

34

Sembra che Hibernate legge il valore di tipo CHAR(n) come Character. Provate a gettarlo ai VARCHAR(n):

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

Quando si utilizza Hibernate tramite Session interfaccia, è possibile explcitly impostare un tipo di risultato con addScalar() invece (accessibile anche tramite unwrap() in 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); 

Ci ci sono un sacco di problemi irrisolti relativi a questo problema in Hibernate JIRA, a partire da HHH-2220.

Ecco una spiegazione di Max Rydahl Andersen da commenti di HHH-2220:

Attualmente Hibernate supporta una sorta di mappatura "automagic" da tipi SQL di Hibernate tipi/Java - a causa delle molte ambiguità nel fare tale mappatura a volte non corrisponderà a ciò che effettivamente si desidera.

Questo è il motivo per cui si consiglia sempre di utilizzare l'addscalar esplicito OPPURE se non si desidera che tutto il codice utilizzi la sottoclasse di Dialect per stabilire quale dei più possibili mapping si desidera.

Il problema con CHAR è il più problematico, ma non è facile da risolvere: avremmo bisogno di un registerType (tipo, from, to, typename) per mappare un intervallo anziché una lunghezza specifica ... ma anche quindi potresti imbatterti in mappature di ambiguità (ad esempio a volte vuoi un array altre volte stringa, ecc.) Quindi utilizzare .addScalar è raccomandato per qualsiasi query sql nativa - a seconda del rilevamento automatico sarà sempre rischioso e dovrebbe essere usato solo al minimo.

Se la query nativa è descritta nel file di configurazione dei mapping di Hibernate, è necessario definire <return-scalar ...> per ogni valore restituito. Nota: è necessario enumerare tutti i valori restituiti, poiché quando si definiscono esplicitamente i tipi restituiti, l'autodiscovery viene disattivato e vengono restituite solo le colonne dichiarate.

<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ì, è tutto. Trovato il problema in base a jira per questa funzione. http://opensource.atlassian.com/projects/hibernate/browse/HHH-2304 – Guus

+0

meravigliosa spiegazione !!! – lwpro2

+1

Ho una colonna come char (10). e ottengo errore quando provo cast (..as VARCHAR). funziona bene quando uso cast (.... come CHAR) – kommradHomer

Problemi correlati