Как я могу запросить значение null в длинном значении без получения "Ожидаемого NUMBER, но получившего BINARY" из OracleDB?

Я использую JPQL и хочу запросить нулевое значение в длинном поле. Но я всегда получаю ORA-00932: непоследовательные типы данных: ожидаемый NUMBER получил BINARY. Как я уже видел, есть много людей, у которых есть проблемы с этим, но есть ли у кого-нибудь обходные пути для этого?

Например, это запрос "SELECT a FROM Auftrag a WHERE :id is null OR a.id = :id" и позже я устанавливаю id с помощью setParameter("id", null). Это используется в более сложном запросе для цели фильтрации, поэтому null означает в нашем случае игнорировать фильтр в столбце.

Кто-нибудь, у кого есть идея?

С уважением!

Ответ 1

Я не знаю специфики 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.
END EDIT

Возможно, вы столкнулись с проблемой в JPQL с помощью

SELECT a FROM Auftrag a WHERE :id is null OR a.id = COALESCE(:id, -1)

по крайней мере, это возможно с помощью родного Hibernate HQL. В этом случае вторая часть условия WHERE оценивается как FALSE, если :id имеет значение null, но все условие WHERE оценивается как TRUE, что вам нужно.

Но для запросов динамической фильтрации лучше использовать API-интерфейс JPA 2.0 Criteria и включать параметр :id в запрос, только если он не является нулевым. Опять же, я не знаю специфики критериев JPA, но с собственными критериями Hibernate это будет

public List<Auftrag> findByFilter(Long id) { 
  Criteria criteria = session.createCriteria(Auftrag.class);
  if (id != null) {
    criteria.add(Restrictions.eq("id", id));
  } // if
  return criteria.list();
}

Надеюсь, что это поможет.

Ответ 2

У меня была та же проблема, я решил ее, обратив сторону 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

работал отлично. Я не понимаю, почему, но это работает. Вероятно, это имеет какое-то отношение к "короткому замыканию", но в любом случае оба утверждения оцениваются в любом случае. Надеюсь, кто-то может это объяснить.

Ответ 3

В Oracle (12) я нашел обходной путь, используя TO_NUMBER:

SELECT a FROM Auftrag a WHERE :id is null OR a.id = TO_NUMBER(:id)

Ответ 4

Коалсис не работает для меня. Я исправил это ограничение, используя неиспользуемое значение (в моем случае -1), чтобы получить правильную фильтрацию

SELECT a FROM Auftrag a WHERE :id = -1 OR a.id = :id