4

JPA 提供了运行原生 SQL 查询的能力:

final Query q = entityManager.createNativeQuery("SELECT hork FROM foobar");
assert q != null;
final List results = q.getResultList();

在上面的查询中, my 中将出现什么样的对象List

看起来很简单,但是:

在我们的例子中,我们有一个 InformixTEXT列。InformixTEXT类型有点CLOB像.

Informix JDBC 驱动程序报告——不管这是否属实,我们都不能改变它——java.sql.Types该列映射到的字段值java.sql.Types#LONGVARCHAR. 好的。

如果您像这样运行常规的旧 JDBC 查询:

final ResultSet rs = someStatement.executeQuery("SELECT hork FROM foobar");
assert rs != null;
while (rs.next()) {
    final Object result = rs.getObject(1);
    // see if you can guess what result.getClass() is
}

...您正在与 合作byte[],而不是String

现在,如果您使用两大 JPA 提供程序(Hibernate、EclipseLink)运行上面的本机查询,您将在结果列表中获得不同的对象。

Hibernate 返回 a String,它只是表单中列的内容String,可能是通过ResultSet#getString(int)(而不是ResultSet#getObject(int))或通过结果的某种平台编码byte[]

EclipseLink 返回 a 的十六进制表示byte[],当以 ASCII 字符集解码和解释时,它确实是列的内容。

我有两个相关的问题:

  1. 如何指示 JPA 标量原生 SQL 查询的类型应该是什么?

  2. 如果 EclipseLink 没有返回String代表列内容的 a ,为什么它不只是返回 a byte[]

4

1 回答 1

0

很奇怪,您的 Informix JDBC 驱动程序将 TEXT 值作为字节 [] 返回,这似乎很错误,因为它是字符字段而不是二进制字段,它应该是字符串。您可能希望查看您的 JDBC 驱动程序是否对此进行了修复。

JPA 似乎将值作为字符串获取,因为 JDBC 元数据说它是字符串。

对于 EclipseLink,真正发生的事情是 LONGVARCHAR 被解释为 Clob 类型,并且由于 Clob 可以只是一个定位器,因此必须获取整个值,因此它将预期的 Clob 转换为字符串,但因为它实际上是一个字节[],它将转换器转换为 HEX。您可以在 InformixPlatofrm 中通过覆盖 isClob 并为 LONGVARCHAR 返回 false 来解决此问题,但真正的问题是 JDBC 驱动程序正在为字符字段返回 byte[]。

于 2013-04-11T17:40:02.180 回答