EclipseLink 中命名查询中的可选参数

问题描述 投票:0回答:2

我是使用 EclipseLink 的 JPA 命名查询的新手,我想“忽略”命名查询中具有空值的属性。我知道我的问题已经被回答过很多次了。 例如JPA 查询处理 NULL 参数值

但是,在我的情况下,以下格式不起作用

+ " AND (:quoteNumber IS NULL OR ord.quoteNumber = :quoteNumber)"

我收到错误“非法使用关键字空”。我现在将使用 CriteriaQuery,只是好奇为什么它在命名查询中不起作用。 以下是正在使用的 DB2 和 Eclipselink 版本。 eclipse链接:2.5.1 DB2:DSN11015

db2 eclipselink named-query db2-zos
2个回答
3
投票

JPA 规范这么说

3.8.13 命名查询
命名查询是用元数据表示的静态查询。命名查询可以用 Java 持久性查询语言或 SQL 来定义。查询名称的范围仅限于持久性单元。

所以你不能真正期望它们在运行时基于某些空条件而改变。正如您所指出的,标准查询本质上是动态的,因此这将是可行的方法。

根据评论进行编辑:

 AND (ord.quoteNumber = :quoteNumber or :quoteNumber is null or :quoteNumber = '' 

不更改运行时的查询(不跳过子句)。它将该子句评估为 TRUE。 DB2(以及据我所知的 Derby)的问题是,它们不允许按照 API PreparedStatement.setObject“将非类型化 Null 发送到后端”。您可以通过强制转换设置类型来测试它 AND (ord.quoteNumber = cast(:dfdTxt as integer) or cast(:dfdTxt as integer) is null or cast(:dfdTxt as integer) = ''

因此,这种方法是特定于数据库实现的,并且可能会在某些时候发生变化。


0
投票

TL;DR:我通过在 SQL 语句中转换虚拟列数据类型来修复错误 - 检查最后一个代码框。

持久性.xml:

<properties> <property name="eclipselink.ddl-generation" value="none" /> <property name="eclipselink.ddl-generation.output-mode" value="database" /> <property name="javax.persistence.jdbc.url" value="jdbc:h2:mem:mydb;DB_CLOSE_DELAY=-1;MODE=Oracle;DEFAULT_NULL_ORDERING=HIGH"/> <property name="javax.persistence.jdbc.driver" value="org.h2.jdbcx.JdbcDataSource"/> <property name="eclipselink.logging.level" value="SEVERE" /> <property name="eclipselink.logging.parameters" value="false" /> <property name="eclipselink.target-database" value="Oracle"/> </properties>

NamedQuery 失败:

NamedQuery( name = "myquery", query = " select count(job.id), 'job' as tabelle" + " from Job job" " UNION" + " select count(xyz.id), 'xyz' as tabelle" + " from Xyz xyz" )

结果:

Caused by: Exception [EclipseLink-4002] (Eclipse Persistence Services - 2.7.14.v20231208-d05cebc9b0): org.eclipse.persistence.exceptions.DatabaseException Internal Exception: org.h2.jdbc.JdbcSQLNonTransientException: Unbekannter Datentyp: "?, ?" Unknown data type: "?, ?"; SQL statement: (SELECT COUNT(t0.ID), ? FROM JOB t0) [50004-224] Error Code: 50004

可以通过在 SQL Select 语句中使用 
cast()

来修复此错误:

@NamedQuery(
        name = "myquery",
        query = " select count(job.id), cast('job' as VARCHAR2(30)) as tabelle" +
                " from Job job"
                " UNION" +
                " select count(xyz.id), cast('xyz' as VARCHAR2(30)) as tabelle" +
                " from Xyz xyz"

)

© www.soinside.com 2019 - 2024. All rights reserved.