Hibernate 本机查询 - char(3) 列
Posted
技术标签:
【中文标题】Hibernate 本机查询 - char(3) 列【英文标题】:Hibernate native query - char(3) column 【发布时间】:2011-06-19 21:08:53 【问题描述】:我在 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
o[0]
是一个 java.lang.Character
如何获得EUR
和USD
的完整值?
【问题讨论】:
【参考方案1】:看起来 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>
【讨论】:
是的,就是这样。找到了此功能的相应 jira 问题。 opensource.atlassian.com/projects/hibernate/browse/HHH-2304 我有一列是 char(10)。当我尝试强制转换(..as VARCHAR)时出现错误。当我使用 cast(.... as CHAR) 时它工作正常 我有一个 CHAR(1) 列,当使用 hibernate 和简单的 createQuery 时,它可以通过 hibernate 正确处理为字符串,但是当我使用 createNativeQuery 时,因此跳过休眠引擎,我必须采用你的查询中的建议:选择 cast(my_flag as VARCHAR2(1))。它有效 难以置信。我正在使用 Hibernate 3.2 并在尝试选择“文字”时遇到了这个问题:select 'Hello' from dual
(Oracle) 得到了简单的“H”,真是个笑话!在我的案例中,唯一的解决方案是应用 .addScalar,没有一个 CAST 选项对我有用。以上是关于Hibernate 本机查询 - char(3) 列的主要内容,如果未能解决你的问题,请参考以下文章
Hibernate:使用@SqlResultSetMapping 映射本机查询的结果集