Как я могу запросить нулевое значение Long, не получая «Ожидаемый номер, но получил BINARY» от OracleDB? - PullRequest
11 голосов
/ 27 декабря 2011

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

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

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

С уважением!

Ответы [ 3 ]

6 голосов
/ 27 декабря 2011

Я не знаю ни специфики JPQL, ни того, как Oracle обрабатывает условие WHERE вашего запроса.Но я бы поспорил, что вторая часть вашего условия WHERE не полностью игнорируется и что a.id = NULL вызывает проблему.Помимо явно несовместимых типов данных условие, подобное some_value = NULL, может оцениваться не в ИСТИНА или ЛОЖЬ, а в ПУСТО (по крайней мере, это происходит в PostgreSQL).Для вашего конкретного случая использования объединенное условие :id IS NULL OR a.id = NULL по-прежнему работает так, как задумано в PostgreSQL.Но в другом контексте вы не получите строк с some_value = NULL, даже если some_value равно нулю.Поэтому я считаю, что ради надежного и понятного кода в любом случае следует избегать выражения типа 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 и включать в запрос параметр :id, только если он не равен нулю.Опять же, я не знаю особенностей JPA Criteria, но с родными Hibernate Criteria это будет

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();
}

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

5 голосов
/ 18 июля 2013

У меня была такая же проблема, я решил ее, изменив стороны ИЛИ, например:

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

не работал, но изменил стороны ИЛИ, как это:

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

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

1 голос
/ 09 января 2019

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

SELECT a FROM Auftrag a WHERE :id is null OR a.id = TO_NUMBER(:id)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...