【问题标题】:IS NULL check not working on list in JPA SQL QueryIS NULL 检查不适用于 JPA SQL 查询中的列表
【发布时间】:2021-02-21 02:42:22
【问题描述】:

我有以下带有 where 子句的 JPA 查询:

@Query("SELECT P FROM ParentEntity P \n" +
"INNER JOIN P.childEntities C \n" +
"WHERE C.childId IN (:childIds)")
List<ParentEntity> findByChildIds(@Param("childIds") List<UUID> childIds);

childId 列在表中是 notnull,所有行都有该列的值。

childIds 参数有值时,

查询工作正常。但是 childIds 是一个可选参数,它可能是一个空列表或 null,在这种情况下我想忽略 where 子句并简单地返回

SELECT P FROM ParentEntity P \n" +
    "INNER JOIN P.childEntities C

所以我将查询修改为:

@Query("SELECT P FROM ParentEntity P \n" +
"INNER JOIN P.childEntities C \n" +
"WHERE ((:childIds) IS NULL OR C.childId IN (:childIds))")
List<ParentEntity> findByChildIds(@Param("childIds") List<UUID> childIds);

现在,当 childIds 为空 (= []) 时,此查询返回 0 个结果,因为 (:childIds) IS NULL 为假,C.childId IN (:childIds) 也始终为假。但我想要这种情况下的所有行。

childIdsnull时,则抛出异常:

org.postgresql.util.PSQLException: ERROR: could not determine data type of parameter $1

我希望所有行也返回这里,而不是例外。

【问题讨论】:

  • 尝试添加or :childIds = []
  • 给出 QuerySyntaxException
  • 尝试使用COALESCE(:childIds, null) is null

标签: sql postgresql jpa spring-data-jpa


【解决方案1】:

您确实有 2 个单独的查询,因此与其将逻辑隐藏在 SQL 中,不如将其移动到 default 方法中选择适当的直接 JPA 方法:

default List<ParentEntity> findByChildIds(List<UUID> childIds) {
    if (childIds == null || childIds.isEmpty()) {
        return getAll();
    }
    return getByChildIds(childIds);
}

@Query("SELECT P FROM ParentEntity P \n" +
"INNER JOIN P.childEntities C \n" +
"WHERE C.childId IN (:childIds)")
List<ParentEntity> getByChildIds(@Param("childIds") List<UUID> childIds);

@Query("SELECT P FROM ParentEntity P \n" +
"INNER JOIN P.childEntities C")
List<ParentEntity> getAll();

这使 SQL 更易于阅读,逻辑更易于遵循,而且它为数据库提供了更好的优化机会。

在这里为所有方法命名 - 他们不需要使用 JPA 方法关键字。

我已经在生产中使用了这种方法,效果很好。

【讨论】:

  • 是的,最后不得不这样做。
【解决方案2】:

在这种情况下,您可以创建 2 个请求,并根据您的参数选择要使用的请求。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-01-19
    • 1970-01-01
    • 2020-02-18
    • 2018-08-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多