为什么此 JPA 查询在 H2 数据库上失败?

Why does this JPA query fail on a H2 database?

我在 Spring 数据接口

中定义了以下 JPA 查询
@Query("select tr.bidder.supplierId " +
    "from   TaskResponse tr " +
    "where  tr.task.id = :taskId " +
    "and    tr.extended = true " +
    "and    tr.bidder.supplierId not in (:extendedSupplierIds)")
Set<String> supplierIdsDueTaskRevocationNotification(UUID taskId,
        Set<String> extendedSupplierIds);

查询在针对 Postgres 数据库执行时工作正常,但在针对 H2 数据库执行时失败并出现以下错误:

Syntax error in SQL statement 

SELECT BIDDER1_.SUPPLIER_ID AS COL_0_0_ 
FROM TASK_RESPONSES TASKRESPON0_ 
CROSS JOIN BIDDERS BIDDER1_ 
WHERE TASKRESPON0_.BIDDER_ID=BIDDER1_.ID 
AND TASKRESPON0_.TASK_ID=? 
AND TASKRESPON0_.EXTENDED=1 
AND (BIDDER1_.SUPPLIER_ID NOT IN  ()[*])"; 

expected "NOT, EXISTS, INTERSECTS, UNIQUE"; 

问题似乎出在 not in (:extendedSupplierIds) 谓词上,因为如果我删除这个谓词,查询将在两个数据库上正常执行。

有什么方法可以重写查询,以便它在两个数据库上都能工作?

更新

根据一位受访者的建议,我将查询更改为使用显式连接

@Query("select b.supplierId " +
    "from   TaskResponse tr " +
    "join   tr.bidder b " +
    "join   tr.task t " +
    "where  t.id = :taskId " +
    "and    tr.extended = true " +
    "and    b.supplierId not in (:extendedSupplierIds)")
Set<String> supplierIdsDueTaskRevocationNotification(UUID taskId,
        Set<String> extendedSupplierIds);

但这没有什么区别,我仍然得到同样的错误。

这是由 org.hibernate.dialect.H2Dialect.

中的错误引起的

如果您传递一个空集作为查询参数值,它构成 JPQL 查询中“不在”谓词的右侧,则当 运行 针对 H2 数据库时查询失败。要解决此问题,请使用包含 取而代之的是单个空元素。

例如在你调用这个查询的地方使用

UUID taskId = UUID.randomUUID();
Set<String> supplierIds = // get this from somewhere

if (supplierIds.isEmpty()) {
  supplierIds.add(null);
}

myRepository.supplierIdsDueTaskRevocationNotification(taskId, supplierIds)