Hibernate本机查询 - char(3)列

时间:2011-02-02 10:19:51

标签: java oracle hibernate jpa seam

我在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=Ecur=U而不是cur=EURcur=USD

o[0]是一个java.lang.Character

如何获得完整值EURUSD

1 个答案:

答案 0 :(得分:36)

看起来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评论的Max Rydahl Andersen的解释:

  

目前,Hibernate支持从SQL类型到Hibernate / Java类型的一种“自动”映射 - 由于执行此类映射时存在许多歧义,因此有时不符合您的实际需求。

     

这就是为什么我们总是建议使用显式的addScalar OR,如果你不希望你的代码全部使用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>