如何在不获取OracleDB的“预期NUMBER但得到BINARY”的情况下查询Long值中的null?
我正在使用JPQL,并希望在Long字段中查询空值。 但我总是得到一个ORA-00932:不一致的数据类型:预期NUMBER得到了BINARY。 正如我所见,有很多人对此有疑问,但有人有解决方法吗?
例如,这是查询"SELECT a FROM Auftrag a WHERE :id is null OR a.id = :id"
,稍后我用setParameter("id", null)
设置id。这用于更复杂的查询过滤目的,所以null在我们的例子中意味着忽略列上的filter。
有想法的人吗?
亲切的问候!
我不知道JPQL的细节以及Oracle如何处理查询的WHERE条件。 但我敢打赌,你的WHERE条件的第二部分并没有被完全忽略 ,而a.id = NULL
导致了这个问题。 除了明显不一致的数据类型之外, some_value = NULL
之类的条件可能不会计算为TRUE或FALSE而是计算为NULL(至少这种情况发生在PostgreSQL上)。
编辑
对于您的特定用例,组合条件:id IS NULL OR a.id = NULL
仍然在PostgreSQL上按预期工作。 但是在另一个上下文中,即使some_value
为null,也不会获得some_value = NULL
任何行。 因此,我认为为了强大且易于理解的代码,在任何情况下都应该避免使用像some_value = NULL
这样的表达式。
结束编辑
您可以在JPQL中解决此问题
SELECT a FROM Auftrag a WHERE :id is null OR a.id = COALESCE(:id, -1)
至少这可以使用原生Hibernate HQL。 在这种情况下,WHERE条件的第二部分求值为FALSE if :id
为null但整个WHERE条件的计算结果为TRUE,这就是你想要的。
但是对于动态过滤查询,更好的方法是使用JPA 2.0 Criteria API,并且只有在它不为null时才在查询中包含:id
参数。 同样,我不知道JPA Criteria的具体细节,但是使用原生的Hibernate Criteria
public List findByFilter(Long id) { Criteria criteria = session.createCriteria(Auftrag.class); if (id != null) { criteria.add(Restrictions.eq("id", id)); } // if return criteria.list(); }
希望有所帮助。
我有同样的问题,我通过反转OR侧解决了它,例如:
SELECT a FROM Auftrag a WHERE :id is null OR a.id = :id
没有工作,但像这样扭转OR方面:
SELECT a FROM Auftrag a WHERE a.id = :id OR :id is null
工作得很好。 我不明白为什么,但它的确有效。 它可能与“短路”有关,但是在null的情况下,无论如何都要评估两个语句。 希望有人可以解释一下。
- 如何在Spring Applications中处理生产数据库的模式升级
- Hibernate,liquibase和hsqldb的Id生成问题
- 如何使用JPA和Hibernate加入两个不相关的实体
- 使用Hibernate OGM进行MongoDb身份validation
- HibernateException:无法获取当前线程的事务同步会话
- 提高了PostgreSQL查询性能,并且已经连接了1亿个数据
- 如何使用Hibernate为Spring数据JPA的所有查找方法添加全局where子句?
- hibernate composite主键包含一个复合外键,如何映射这个
- 我们什么时候应该关闭EntityManagerFactory?