Ebean - 动态查询 - 准备语句的不匹配参数计数错误

时间:2013-12-10 17:45:36

标签: java mysql playframework-2.0 ebean

我希望拥有比我更多Ebean专业知识的人可以帮助我解决我现在正在排除故障的不稳定问题。

环境:

  • Java 1.7.0_17
  • MySQL 5.5
  • Play Framework 2.1.1(但我已升级到Play 2.2.1,此问题仍然存在)

我的主要问题是,当我重新启动Play时,我正在交替使用SQLExceptions,所有这些都与Ebean正在创建的预准备语句中的参数太多或太少有关。数据集A在数据集B失败的一半时间内工作,但在重新启动Play时,数据集B在数据集A失败时有效。

我正在根据我写入传递给函数的一组Filter对象动态构建一个Ebean Query对象。 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).

然后在Play重启后,数据集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%可靠地切换。

有没有人见过这样的事情?只是为了增加混乱,它还在我们的生产环境中做了非常类似的事情(在不同的数据集上),但即使在转储数据库并在本地加载它之后,我也无法在我的开发或测试机器上重现这一点。上述问题虽然可以在任何地方重现。

2 个答案:

答案 0 :(得分:0)

我在使用预处理语句时看到了类似的东西(在DB2上)。 Querties仅适用于执行第一个语句的参数数量。只有第一次调用或更少的参数数量才有效。它可能为参数留出了一个缓冲区 - 我认为它的作用就像额外的参数不存在一样。

如果第一次调用有足够的参数,那么一切都会好的,直到你击中超过这个数量的参数。但是,如果第一个查询只有1个参数且下一个调用有多个参数,则下一次运行可能会立即失败。

检查它是否适用于常规语句而不是预准备语句。如果是这样,怀疑准备好的语句中的错误处理可变数量的参数。

答案 1 :(得分:-2)

Tags()数组列表中有一个空值。如果您调试代码,您可以看到标记数组中有一个空值。