我正在使用 z/OS 上的 DB2 12 将应用程序从 WebSphere 8.5 上带有 OpenJPA 的 JPA 2.0 迁移到 WebSphere 9.0 上带有 EclipseLink 的 JPA 2.1。通常它可以工作,但是一个相当复杂的查询失败了。我可以将问题定位为在标准查询中使用自定义 DB2 函数调用。调用看起来像这样:
criteriaBuilder.function("REPLACE", String.class, fromMyEntity.get("myField"), criteriaBuilder.literal("a"), criteriaBuilder.literal("b"));
这会产生以下错误(必须翻译一些错误文本,因为 WebSphere 将它们本地化,并匿名化我的字段/表名称,因此标签/名称可能不是 100% 准确):
Error: Exception [EclipseLink-4002] (Eclipse Persistence Services - 2.6.3.WAS-v20160414-bd51c70): org.eclipse.persistence.exceptions.DatabaseException
Internal Exception: com.ibm.websphere.ce.cm.StaleConnectionException: DB2 SQL Error: SQLCODE=-171, SQLSTATE=42815, SQLERRMC=2;REPLACE, DRIVER=3.72.44
Errorcode: -171
Call: SELECT COUNT(ID) FROM MY_TABLE WHERE REPLACE(MYFIELD, ?, ?) LIKE ?
bind => [abc, def, %g%]
Query: ReportQuery(referenceClass=MyEntity sql="SELECT COUNT(ID) FROM MY_TABLE WHERE REPLACE(MYFIELD, ?, ?) LIKE ?").
真正让我感到困惑的是,如果我使用生成的查询,用给定的绑定参数替换占位符,然后自己在数据库客户端中执行它,它就可以正常工作。
文档指出,第一个参数不能为空(https://www.ibm.com/support/knowledgecenter/en/SSEPEK_12.0.0/sqlref/src/tpc/db2z_bif_replace.html),如果我使用的是空的字符串作为查询或我的数据库客户端中的文字,它将产生上述错误。但是数据库中没有任何行包含空值。在旧环境中进行了检查以防止这种情况发生,但它们似乎不适用于新环境,因此我在搜索问题时禁用了它们,并确保自己不存在空值。我什至可以使用主键作为第一个参数,它仍然会失败,甚至不能包含空/空值。
使用其他函数(如 TRANSLATE)可以工作,我也尝试使用“SYSIBM.REPLACE”作为名称和不同的参数组合,但是一旦我使用真实列替换数据,它就会失败。有人知道我在这里做错了什么吗?
这是我的表定义:
CREATE TABLE "MY_TABLE" (
"ID" INTEGER NOT NULL GENERATED BY DEFAULT AS IDENTITY (NO MINVALUE NO MAXVALUE NO CYCLE CACHE 20 NO ORDER ),
"MYFIELD" VARCHAR(160) FOR MIXED DATA WITH DEFAULT NULL,
[....]
) IN "<Database>"."<Tablespace>" PARTITION BY SIZE EVERY 4 G AUDIT NONE DATA CAPTURE NONE CCSID UNICODE;