看起来 Hibernate 将 CHAR(n) 类型的值读取为 Character。尝试将其转换为VARCHAR(n):
Query q2 = em.createNativeQuery(
"select cast(sc_cur_code as VARCHAR2(3)), sc_amount from sector_costs");
当通过Session 接口使用Hibernate 时,您可以改为使用addScalar() 显式设置结果类型(在JPA 2.0 中也可以通过unwrap() 访问):
Query q2 = em.createNativeQuery(
"select sc_cur_code, sc_amount from sector_costs");
q2.unwrap(SQLQuery.class).addScalar("sc_cur_code", StringType.INSTANCE);
从HHH-2220开始,Hibernate JIRA中有很多与此问题相关的未解决问题。
这是来自 HHH-2220 的 cmets 的 Max Rydahl Andersen 的解释:
目前,Hibernate 支持一种从 SQL 类型到 Hibernate/Java 类型的“自动”映射 - 由于在进行此类映射时存在许多模糊性,它有时会与您实际想要的不匹配。
这就是为什么我们总是建议使用显式 addScalar 或者如果您不希望在整个代码中使用 Dialect 的子类来指示您想要多个可能的映射中的哪一个。
CHAR 的问题是最成问题的问题,但它不容易解决——我们需要一个 registerType(type, from, to, typename) 来映射一个范围而不是一个特定的长度......但即便如此您可能会遇到映射歧义(例如,有时您需要一个数组,其他时间是字符串等)。因此,对于任何本机 sql 查询,建议使用 .addScalar - 取决于自动发现总是有风险的,并且应该只使用到最低限度。
如果您在 Hibernate 映射配置文件中描述了您的本机查询,那么您需要为每个返回的值定义 <return-scalar ...>。注意:您必须枚举所有返回值,因为当您显式定义返回类型时,自动发现将被关闭,并且仅返回声明的列。
<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>