Oracle
 sql >> Base de Dados >  >> RDS >> Oracle

Consulta nativa de hibernação - coluna char(3)


Parece que o Hibernate lê o valor do tipo CHAR(n) como Character . Tente convertê-lo para VARCHAR(n) :
Query q2 = em.createNativeQuery(
    "select cast(sc_cur_code as VARCHAR2(3)), sc_amount from sector_costs");  

Ao usar o Hibernate via Session interface, você pode definir explicitamente um tipo de resultado com addScalar() em vez disso (também acessível via unwrap() em 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);

Existem muitos problemas não resolvidos relacionados a este problema no Hibernate JIRA, começando pelo HHH-2220.

Aqui está uma explicação de Max Rydahl Andersen dos comentários do HHH-2220:

Atualmente, o Hibernate suporta um tipo de mapeamento "automágico" de tipos SQL para tipos Hibernate/Java - devido às muitas ambiguidades em fazer esse mapeamento, às vezes não corresponderá ao que você realmente deseja.

É por isso que sempre recomendamos usar addScalar OR explícito se você não quiser que em todo o seu código use a subclasse de Dialect para ditar qual dos vários mapeamentos possíveis você deseja.

O problema com CHAR é o mais problemático, mas não é fácil de corrigir - precisaríamos de um registerType(type, from, to, typename) para mapear um intervalo em vez de um comprimento específico... em ambiguidades de mapeamento (por exemplo, às vezes você quer uma matriz outras vezes string etc.) Portanto, o uso de .addScalar é recomendado para qualquer consulta sql nativa - dependendo da descoberta automática, sempre será arriscado e deve ser usado apenas no mínimo.

Se você tiver sua consulta nativa descrita no arquivo de configuração de mapeamentos do Hibernate, precisará definir <return-scalar ...> para cada valor retornado. Observação:você deve enumerar todos os valores retornados, pois quando você define os tipos de retorno explicitamente, a descoberta automática é desativada e apenas as colunas declaradas são retornadas.
<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>