我在Oracle中有一个表,其中SC_CUR_CODE列为CHAR(3)
当我做:
Query q2 = em.createNativeQuery("select sc_cur_code, sc_amount from sector_costs"); q2.setMaxResults(10); List<Object[]> rs2 = q2.getResultList(); for (Object[] o : rs2) { System.out.println(">>> cur=" + o[0]); }
我看到了cur=E,cur=U而不是cur=EUR和cur=USD
cur=E
cur=U
cur=EUR
cur=USD
o[0] 是一个java.lang.Character
o[0]
我怎样才能得到充分的价值EUR和USD?
EUR
USD
似乎Hibernate读取类型CHAR(n)为的值Character。尝试将其转换为VARCHAR(n):
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()(也可以通过unwrap()JPA 2.0 访问):
Session
addScalar()
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评论中的Max Rydahl Andersen的解释:
当前,Hibernate支持从SQL类型到Hibernate / Java类型的一种“自动”映射- 由于这种映射存在很多歧义,因此有时可能与您实际想要的不匹配。 这就是为什么我们总是建议使用显式的addScalar OR的原因,如果您不希望整个代码都使用Dialect的子类来指示您想要多个可能的映射中的哪个。 CHAR的问题是最成问题的,但解决起来并不容易- 我们需要一个registerType(type,from,to,typename)来映射一个范围而不是特定的长度…但是即使那样您也可能碰到映射为模糊性(例如,有时需要数组,而有时需要字符串等),因此建议对任何本机sql查询使用.addScalar- 取决于自动发现将总是有风险的,并且仅应使用最少。
当前,Hibernate支持从SQL类型到Hibernate / Java类型的一种“自动”映射- 由于这种映射存在很多歧义,因此有时可能与您实际想要的不匹配。
这就是为什么我们总是建议使用显式的addScalar OR的原因,如果您不希望整个代码都使用Dialect的子类来指示您想要多个可能的映射中的哪个。
CHAR的问题是最成问题的,但解决起来并不容易- 我们需要一个registerType(type,from,to,typename)来映射一个范围而不是特定的长度…但是即使那样您也可能碰到映射为模糊性(例如,有时需要数组,而有时需要字符串等),因此建议对任何本机sql查询使用.addScalar- 取决于自动发现将总是有风险的,并且仅应使用最少。
如果您在Hibernate映射配置文件中描述了本机查询,则需要<return-scalar ...>为每个返回的值进行定义。注意:您必须枚举所有返回的值,因为当您显式定义返回类型时,自动发现将关闭并且仅返回声明的列。
<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>