2013-12-10 3 views
15

Ich hoffe, dass jemand mit mehr Ebean-Expertise als ich mit einem fehlerhaften Problem behilflich sein kann.Ebean - Dynamische Abfrage - Anzahl der nicht übereinstimmenden Parameter der vorbereiteten Anweisung

Die Umgebung:

  • Java 1.7.0_17
  • MySQL 5.5
  • Play-Framework-2.1.1 (aber ich habe ein Upgrade 2.2.1 zu spielen und dieses Problem noch existierte)

Mein Hauptproblem ist, dass ich beim Starten von Play alternierende SQLExceptions bekomme, die entweder mit zu vielen oder zu wenigen Parametern in der vorbereiteten Anweisung, die Ebean erstellt, zu tun haben. Datensatz A funktioniert die Hälfte der Zeit, wenn Datensatz B fehlschlägt, aber beim Neustart von Play funktioniert Datensatz B, während Datensatz A fehlschlägt.

Ich bin ein Ebean Query-Objekt dynamisch basierend auf einem Set von Filter-Objekten, die ich geschrieben habe, in eine Funktion übergeben. Die Ebean-Abfrage findet alle Objekte, die die gegebenen Anforderungen jedes Filters erfüllen.

Die Funktion ist ähnlich wie:

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

Ein Beispiel für einen Filter:

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

Zunächst einmal ist diese Art der Abfrage Gebäude in Ebean unterstützt? Ich glaube es ist wie das funktioniert die meiste Zeit, aber ich bekomme Probleme mit der Ausführung der "getContacts" -Funktion mehrere hundert Mal mit bestimmten Daten, aber nur manchmal ...

Also bleib bei mir, wie dieses Problem ist sehr verwirrend. Ich werde auch über die meisten Details der tatsächlichen Daten blättern, aber wenn Sie weitere Informationen benötigen/benötigen, fragen Sie bitte.

Datensatz Eine Abfrage und Ausnahme:

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). 

Dann, nach einem Spiel Neustart gesetzt Daten B Abfrage und Ausnahme:

[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 (?,?,?,?,?,?,?,?,?,?,?,?) ] 

Ich glaube, dass die verwirrendsten Stück über dieses ist es, wie schaltet zuverlässig 100% der Zeit beim Neustart hin und her.

Hat jemand schon einmal so etwas gesehen? Um die Verwirrung noch zu verstärken, wird in unserer Produktionsumgebung etwas Ähnliches (auf verschiedenen Datensätzen) gemacht, aber ich kann dies nicht auf meinen Entwicklungs- oder Testmaschinen reproduzieren, selbst nachdem die Datenbank gedumpt und lokal geladen wurde. Das oben beschriebene Problem ist jedoch überall reproduzierbar.

+0

Sieht so aus, als wäre dies ein Fehler in Ebean, an dem wir gerade arbeiten: https://github.com/ebean-orm/avaje-ebeanorm/issues/60 – jcreason

+0

Ist das immer noch ein Problem? Wir sollten diese Frage wahrscheinlich beantworten und abschließen. – avgvstvs

+0

Ich konnte es nie lösen und habe dieses Problem gelöst, bevor Rob eine Lösung für das Ebean-Projekt einreichte. – jcreason

Antwort

-2

Es gibt einen Nullwert in der Array-Liste Tags(). Wenn Sie den Code debuggen, können Sie sehen, dass im Tag-Array ein Nullwert vorhanden ist.

+0

Auch wenn es im Ergebnis der Funktion getTags() einen Nullwert gibt, von dem ich annehme, dass Sie darauf verweisen, hätte dies nicht verursacht. – jcreason

0

Ich habe etwas ähnliches (auf DB2) mit vorbereiteten Anweisungen gesehen. Queries funktionierten nur für die Anzahl der Parameter, die die erste Anweisung ausgeführt hatte. Nur die Anzahl der Parameter, die es beim ersten Aufruf oder weniger aufgerufen hatte, würde funktionieren. Wahrscheinlich hat er einen Puffer für die Parameter reserviert - ich glaube, es hat so funktioniert, als ob die zusätzlichen Parameter nicht existierten.

Wenn der erste Aufruf genug Parameter hatte, dann wäre alles in Ordnung, bis Sie mehr als diese Anzahl von Parametern getroffen haben. Der nächste Lauf kann jedoch sofort fehlschlagen, wenn die erste Abfrage nur einen Parameter und der nächste mehrere hat.

Überprüfen Sie, ob es mit einer regulären Anweisung anstelle einer vorbereiteten Anweisung funktioniert. Wenn dies der Fall ist, wird ein Fehler bei der Verarbeitung vorbereiteter Anweisungen für variable Anzahl von Parametern vermutet.

Verwandte Themen