【发布时间】:2017-09-19 10:21:21
【问题描述】:
在org.springframework.data.jpa.repository.@Query 注释中,我检查集合中的字段,如果它为空,则可能忽略集合:
@Query(""select e from #{#entityName} where e.type in :lst or 0 = :lstSize")
List<Entity> findByLst(@Param("lst") List<XEnum> lst, @Param("lstSize") int lstSize);
我将代码称为:
List<XEnum> lst = ...;
int lstSize = (lst == null) ? 0 : lst.size();
findByLst(lst, lstSize);
对于 lst = null Hibernate 记录的 Oracle DB:
DEBUG [nio-8443-exec-4] org.hibernate.SQL
entity0_.type in (?) or 0=?
TRACE [nio-8443-exec-4] org.hibernate.type.EnumType
Binding null to parameter: [1]
TRACE [nio-8443-exec-4] org.hibernate.type.descriptor.sql.BasicBinder
binding parameter [2] as [INTEGER] - [0]
对于lst = new LinkedList<>() Hibernate 的情况:
DEBUG [nio-8443-exec-5] org.hibernate.SQL
entity0_.type in ( ) or 0=?
TRACE [nio-8443-exec-5] org.hibernate.type.descriptor.sql.BasicBinder
binding parameter [1] as [INTEGER] - [0]
ERROR [nio-8443-exec-5] org.hibernate.engine.jdbc.spi.SqlExceptionHelper
ORA-00936: missing expression
它在 SQL*PLUS 中的语法也是无效的:
select 1 from dual where 1 in ();
我可以省略 lstSize 并仍然检查是否未提供集合 - 返回所有元素吗?
如何处理空列表和 Oracle () 语法错误?
实际上,我有一个大型 JPQL 表达式,可以通过单个调用处理几种空参数的情况。我的目标是使用 if/else 或 Critetia builder 来保持简单的方法,而不是编写几个专门的方法...
例如忽略空参数可以存档:
... and (e.field = :fieldVal or :fieldVal is null)
更新相关资源:
- Passing empty list as parameter to JPA query throws error
- https://hibernate.atlassian.net/browse/HHH-8091(Hibernate 产生 SQL - “in ()” - 至少在 Oracle、MySQL 和 Postgres 中无效)
【问题讨论】:
标签: hibernate jpa spring-data spring-data-jpa jpql