什么控制标量JPA本机查询的List元素类型?

时间:2013-04-10 22:38:49

标签: jpa eclipselink

JPA提供了运行本机SQL查询的功能:

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

在上面的查询中,我的List会出现什么样的对象?

似乎很简单,但是:

在我们的示例中,我们有一个Informix TEXT列。 Informix TEXT type有点像CLOB

Informix JDBC驱动程序报告 - 如果这是真的,我们无法更改它 - java.sql.Types field value to which this column is mappedjava.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

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

Hibernate返回String,它只是String形式的列内容,可能是通过ResultSet#getString(int)(而非ResultSet#getObject(int))或通过某些平台编码结果byte[]

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

我有两个相关的问题:

  1. 如何指示JPA标量本机SQL查询的类型 应该是吗?

  2. 如果EclipseLink没有向我返回代表该列内容的String,那么为什么它不仅仅返回byte[]

1 个答案:

答案 0 :(得分:0)

你的Informix JDBC驱动程序将TEXT值作为byte []返回是很奇怪的,这看起来非常错误,因为它是一个字符字段而不是二进制字段,它应该是一个字符串。您可能希望看看您的JDBC驱动程序是否有针对此的修复程序。

JPA似乎将值作为String获取,因为JDBC元数据表明它是一个String。

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