Ebean - Динамический запрос - Подготовленная заявка Неисправленная ошибка счетчика параметров

Я надеюсь, что кто-то, у кого больше опыта в Ebean, чем я, может помочь мне с неустойчивой проблемой, которую я сейчас устраняю.

Среда:

  • Java 1.7.0_17
  • MySQL 5.5
  • Play Framework 2.1.1 (однако я обновился до версии 2.2.1, и эта проблема все еще существовала)

Моя основная проблема заключается в том, что я получаю переменные SQLExceptions при перезагрузке Play, все из которых связаны с слишком большим количеством или слишком небольшим количеством параметров в подготовленном заявлении, создаваемом Ebean. Набор данных A работает в половину времени, когда сбой набора данных B, но при перезапуске воспроизведения набор данных B работает, когда сбой набора данных A.

Я создаю объект запроса Ebean динамически на основе объектов Set of Filter, которые я написал, переданы в функцию. Ebean Query находит все объекты, отвечающие заданным требованиям каждого фильтра.

Функция похожа на:

private List<Contact> contacts getContacts(Set<Filter> filters) {
    Query<Contact> query = Contact.find;
    for (Filter filter : filters) {
        filter.apply(query);
    }
    List<Contact> contacts = query.findList();
}

Пример фильтра:

public void apply(Query<Contact> query) {
    query.where().in("tags", getTags());
}

Во-первых, этот тип построения запросов поддерживается в Ebean? Я считаю, что это так, как это работает в большинстве случаев, однако у меня возникают проблемы с запуском функции getContacts несколько сотен раз с определенными данными, но только иногда...

Так держись со мной, так как эта проблема крайне запутанна. Я также собираюсь разглядеть большую часть деталей того, что данные на самом деле, но если вы хотите/нуждаетесь в дополнительной информации, пожалуйста, спросите.

Набор данных Запрос и исключение:

select distinct t0.contact_id c0, t0.contact_uuid c1, t0.bounce c2 
from contact t0
join email_record u1 on u1.contact_id = t0.contact_id 
join contact_tag u2z_ on u2z_.contact_id = t0.contact_id 
join tag u2 on u2.tag_id = u2z_.tag_id  
where u1.status = ?  and t0.unit_id = ?  and u2.tag_id in (?,?,?)  and t0.unit_id in (? )  and t0.campaign_id in (?,?,?,?,?,?,?,?,?,?,?,?)

[PersistenceException: Error with property[19] dt[4]data[1464][java.lang.Integer]]
Caused by: java.sql.SQLException: Parameter index out of range (19 > number of parameters, which is 18).

Затем после перезапуска воспроизведения запрос и исключение набора данных B:

[PersistenceException: Query threw SQLException:No value specified for parameter 19 Bind values:[SENT, 1290, 8988, 13032, 13052, 1290, 96, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 222] Query was: select distinct t0.contact_id c0, t0.contact_uuid c1, t0.bounce c2 from contact t0 join email_record u1 on u1.contact_id = t0.contact_id join contact_tag u2z_ on u2z_.contact_id = t0.contact_id join tag u2 on u2.tag_id = u2z_.tag_id where u1.status = ? and t0.unit_id = ? and u2.tag_id in (?,?) and t0.unit_id in (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ? ) and t0.campaign_id in (?,?,?,?,?,?,?,?,?,?,?,?) ]

Я чувствую, что наиболее запутанная штука об этом заключается в том, как она переключается, надежно 100% времени назад и вперед при перезапуске.

Кто-нибудь когда-нибудь видел что-то подобное раньше? Чтобы добавить к путанице, он также делает что-то очень похожее (на разных наборах данных) в нашей производственной среде, но я не могу воспроизвести это на своих машинах разработки или тестирования даже после сброса базы данных и загрузки ее локально. Проблема, описанная выше, хотя и воспроизводима повсюду.

Ответ 1

Я видел нечто подобное (в DB2) с помощью подготовленных операторов. Querties работал только для количества параметров, которые выполнял первый выполненный оператор. Только количество параметров, которые было в первый раз, когда оно было вызвано или меньше, будет работать. Вероятно, он отложил буфер для параметров - я считаю, что он действовал так, как будто лишних параметров не было.

Если у первого вызова было достаточно параметров, все будет хорошо, пока вы не нажмете больше, чем это число параметров. Но следующий запуск может завершиться неудачно, если первый запрос имеет только один параметр, а следующий вызов - более одного.

Проверьте, работает ли он с регулярным выражением вместо подготовленного оператора. Если есть подозрение на ошибку в подготовленных операторах, обрабатывающих переменные количества параметров.

Ответ 2

В списке меток()() есть нулевое значение. если вы отлаживаете код, вы можете увидеть, что в массиве тегов есть нулевое значение.