Oracle
 sql >> Base de données >  >> RDS >> Oracle

Requête native Hibernate - colonne char(3)

Il semble que Hibernate lit une valeur de type CHAR(n) comme Character . Essayez de le caster en VARCHAR(n) :

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

Lorsque vous utilisez Hibernate via Session interface, vous pouvez explicitement définir un type de résultat avec addScalar() à la place (également accessible via unwrap() dans 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);

Il existe de nombreux problèmes non résolus liés à ce problème dans Hibernate JIRA, à partir de HHH-2220.

Voici une explication de Max Rydahl Andersen à partir des commentaires de HHH-2220 :

Actuellement, Hibernate prend en charge une sorte de mappage "automagique" des types SQL vers les types Hibernate/Java - en raison des nombreuses ambiguïtés dans la réalisation d'un tel mappage, il ne correspondra parfois pas à ce que vous voulez réellement.

C'est pourquoi nous recommandons toujours d'utiliser explicitement addScalar OU si vous ne voulez pas que tout votre code utilise la sous-classe de Dialect pour dicter lequel des multiples mappages possibles vous voulez.

Le problème avec CHAR est le plus problématique, mais il n'est pas facile à résoudre - nous aurions besoin d'un registerType (type, from, to, typename) pour mapper une plage au lieu d'une longueur spécifique ... mais même alors, vous pourriez heurter dans les ambiguïtés de mappage (par exemple, parfois vous voulez un tableau, d'autres fois une chaîne, etc.). Par conséquent, l'utilisation de .addScalar est recommandée pour toute requête sql native - dépendre de la découverte automatique sera toujours risqué et ne doit être utilisé qu'au minimum.

Si votre requête native est décrite dans le fichier de configuration des mappages Hibernate, vous devez définir <return-scalar ...> pour chaque valeur renvoyée. Remarque :Vous devez énumérer toutes les valeurs renvoyées, car lorsque vous définissez explicitement les types de retour, la découverte automatique est désactivée et seules les colonnes déclarées sont renvoyées.

<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>