2013-12-10 4 views
15

自分よりもEbeanの専門知識が豊富な人が、私が今トラブルシューティングをしている不安定な問題を助けてくれることを願っています。Ebean - 動的クエリ - 準備文の不一致のパラメータ数エラー

環境:

  • のJava 1.7.0_17
  • のMySQL 5.5
  • プレイフレームワーク2.1.1(ただし、私は2.2.1を再生するためにアップグレードしたと、この問題は依然として存在していた)

私の主な問題は、Playを再起動したときにSQLExceptionsが交互に表示されることです。すべてが、Ebeanが作成しているプリペアドステートメントのパラメータが多すぎたり、少なすぎたりするためです。データセットAは、データセットBが失敗したときの半分の時間で動作しますが、再生を再開すると、データセットAは失敗しますが、データセットBは機能します。

私は関数に渡したフィルタオブジェクトのセットに基づいて動的にEbeanクエリオブジェクトを構築しています。 Ebeanクエリは、各フィルタの所要量を満たすすべてのオブジェクトを検索しています。

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"関数を実行することに問題がありますが、時には...

非常に混乱しています。私はまた、データの実際の内容のほとんどを詳細に説明しますが、より多くの情報が必要な場合は、質問してください。

データは、Aのクエリと例外を設定します。

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%確実に前後に切り替えます。

誰もこれまでにこのようなことを見たことがありますか?混乱を招くだけでなく、私たちの実稼働環境で(データセットごとに)非常に似たようなことを追加していますが、データベースをダンプしてローカルにロードしても、開発マシンやテストマシンで再現することはできません。しかし、上記の問題はどこでも再現可能です。

+0

これは現在作業中のEbeanのバグです:https://github.com/ebean-orm/avaje-ebeanorm/issues/60 – jcreason

+0

これはまだ問題ですか?おそらくこの質問に答えてそれを閉じてください。 – avgvstvs

+0

私はそれを解決することはできませんでしたが、RobがEbeanプロジェクトに修正を提出する前に、この問題を回避しました。 – jcreason

答えて

-2

タグ()配列リストにnull値があります。コードをデバッグすると、タグ配列にヌル値があることがわかります。

+0

getTags()関数の結果にnull値があったとしても、それはあなたが参照していると仮定していますが、これが原因ではありませんでした。 – jcreason

0

私は準備済みの文を使用して(DB2上で)類似したものを見てきました。クエッタは、実行された最初の文が持つパラメータの数だけ機能しました。最初に呼び出されたときのパラメータの数だけが呼び出されます。おそらく、パラメータ用のバッファを用意しておいたのです。余分なパラメータが存在しないように動作すると思います。

最初の呼び出しで十分なパラメータがあった場合、その数以上のパラメータにヒットするまではすべて正常です。しかし、最初のクエリに1つのパラメータしかなく、次の呼び出しに複数のパラメータがあった場合は、すぐに次の実行に失敗することがあります。

準備済みのステートメントではなく、通常のステートメントで機能するかどうかを確認します。もしそうであれば、可変数のパラメータに対するプリペアドステートメントの処理でエラーが発生すると思われます。

関連する問題