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 mapped是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
。
现在,如果您使用Big Two JPA提供程序(Hibernate,EclipseLink)运行上面的本机查询,您将在结果列表中获得不同的对象。
Hibernate返回String
,它只是String
形式的列内容,可能是通过ResultSet#getString(int)
(而非ResultSet#getObject(int)
)或通过某些平台编码结果byte[]
。
EclipseLink返回byte[]
的十六进制表示,当在ASCII字符集中解码和解释时,确实是该列的内容。
我有两个相关的问题:
如何指示JPA标量本机SQL查询的类型 应该是吗?
如果EclipseLink没有向我返回代表该列内容的String
,那么为什么它不仅仅返回byte[]
?
答案 0 :(得分:0)
你的Informix JDBC驱动程序将TEXT值作为byte []返回是很奇怪的,这看起来非常错误,因为它是一个字符字段而不是二进制字段,它应该是一个字符串。您可能希望看看您的JDBC驱动程序是否有针对此的修复程序。
JPA似乎将值作为String获取,因为JDBC元数据表明它是一个String。
对于EclipseLink,真正发生的是LONGVARCHAR被解释为Clob类型,并且因为Clob可以只是一个定位器,所以必须获取整个值,因此它将预期的Clob转换为String,但是因为它是实际上是一个byte [],它将转换器转换为HEX。您可以通过覆盖isClob并在LONGVARCHAR中返回false来修复InformixPlatofrm中的此问题,但真正的问题是JDBC驱动程序为字符字段返回byte []。