Oracle
 sql >> Datenbank >  >> RDS >> Oracle

Native Abfrage in den Ruhezustand versetzen - Spalte char(3).

Es sieht so aus, als würde Hibernate einen Wert vom Typ CHAR(n) lesen als Character . Versuchen Sie, es in VARCHAR(n) umzuwandeln :

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

Bei Verwendung von Hibernate über Session -Schnittstelle können Sie mit addScalar() explizit einen Ergebnistyp festlegen stattdessen (auch zugänglich über 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);

Es gibt viele ungelöste Probleme im Zusammenhang mit diesem Problem in Hibernate JIRA, beginnend mit HHH-2220.

Hier ist eine Erklärung von Max Rydahl Andersen aus den Kommentaren von HHH-2220:

Derzeit unterstützt Hibernate eine Art "automagisches" Mapping von SQL-Typen auf Hibernate/Java-Typen - wegen der vielen Mehrdeutigkeiten bei der Durchführung eines solchen Mappings wird es manchmal nicht mit dem übereinstimmen, was Sie eigentlich wollen.

Aus diesem Grund empfehlen wir immer, explizites addScalar OR zu verwenden, wenn Sie nicht möchten, dass in Ihrem gesamten Code die Unterklassen von Dialect verwendet werden, um vorzuschreiben, welche der mehreren möglichen Zuordnungen Sie möchten.

Das Problem mit CHAR ist das problematischste, aber es ist nicht einfach zu beheben - wir bräuchten einen registerType(type, from, to, typename), um einen Bereich anstelle einer bestimmten Länge abzubilden ... aber selbst dann könnten Sie stoßen in Mapping-Mehrdeutigkeiten (z. B. möchten Sie z. B. manchmal ein Array oder eine andere Zeichenfolge usw.). Daher wird die Verwendung von .addScalar für alle nativen SQL-Abfragen empfohlen - abhängig von der automatischen Erkennung ist dies immer riskant und sollte nur auf ein Minimum verwendet werden.

Wenn Ihre native Abfrage in der Hibernate-Mappings-Konfigurationsdatei beschrieben ist, müssen Sie <return-scalar ...> definieren für jeden zurückgegebenen Wert. Hinweis:Sie müssen alle zurückgegebenen Werte aufzählen, denn wenn Sie die Rückgabetypen explizit definieren, wird die automatische Erkennung ausgeschaltet und es werden nur deklarierte Spalten zurückgegeben.

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