Oracle
 sql >> Database >  >> RDS >> Oracle

Iberna query nativa - colonna char(3).

Sembra che Hibernate legga il valore di tipo CHAR(n) come Character . Prova a trasmetterlo a 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, puoi impostare esplicitamente un tipo di risultato con addScalar() invece (accessibile anche tramite unwrap() nell'APP 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 sono molti problemi irrisolti relativi a questo problema in Hibernate JIRA, a partire da HHH-2220.

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

Attualmente Hibernate supporta una sorta di mappatura "automagic" dai tipi SQL ai tipi Hibernate/Java - a causa delle molte ambiguità nell'esecuzione di tale mappatura, a volte non corrisponderà a ciò che desideri effettivamente.

Questo è il motivo per cui consigliamo sempre di utilizzare addScalar esplicito OPPURE se non vuoi che su tutto il codice, usa la sottoclasse di Dialect per dettare quale delle molteplici mappature possibili desideri.

Il problema con CHAR è il più problematico, ma non è facile da risolvere:avremmo bisogno di un registerType(type, from, to, typename) per mappare un intervallo invece di una lunghezza specifica... ma anche in questo caso potresti urtare in ambiguità di mappatura (ad es. a volte vuoi un array altre volte una stringa ecc.) Quindi l'uso di .addScalar è consigliato per qualsiasi query sql nativa:a seconda del rilevamento automatico sarà sempre rischioso e dovrebbe essere utilizzato solo al minimo.

Se la tua query nativa è descritta nel file di configurazione delle mappature di Hibernate, devi definire <return-scalar ...> per ogni valore restituito. Nota:devi enumerare tutti i valori restituiti, poiché quando definisci i tipi restituiti in modo esplicito, il rilevamento automatico 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>