0

我的问题的简短版本是:

PreparedStatement ps;
ps = connection.prepareStatement("Insert into T values (?)");
ps.setBoolean(1, true);
ps.executeUpdate();

此代码示例生成包含在引号中的值的查询的原因可能是什么?

我的问题的长版本是:

我有用于数据库交互的纯 JDBC 的 JavaEE 应用程序,最近我注意到MySQLDataTruncation我的日志中出现了一些异常。这些异常发生在尝试将实体保存到具有定义为布尔列的 DB 表中BIT(1)。这是因为生成的查询看起来像这样:

Insert into T values ('1');

请注意,值用引号括起来。log.info(ps);使用 Log4J语句从应用程序记录查询。以前的日志表明那里没有引号。

此外,甚至 MySQL 服务器日志也开始看起来有所不同。在这发生之前,我已经为每个执行的查询提供了成对的记录:

12345 Prepare Insert into T values (?)
12345 Execute Insert into T values (1)

之后:

12345 Query Insert into T values ('1')

值得注意的是,这些更改不是部署新版本应用程序甚至重新启动 MySQL/应用程序服务器的结果,负责查询生成的代码就像这个问题中的示例一样简单。

应用程序服务器重启解决了大约 12 小时的问题,然后再次发生。作为临时解决方案,我将BIT列更改为TINYINT

PS 检查应用程序和 MySQL 的日志可以将出错的时间跨度缩小到 2 分钟左右,但在此期间的日志中没有任何异常。

PPS 应用服务器为 Glassfish 2.1.1,MySQL 服务器版本为 5.5.31-1~dotdeb,MySQL Connector/J 版本为 5.0.3。

4

1 回答 1

0

好吧,事实证明这实际上是未封闭的准备好的语句的问题。当 MySQL 服务器上打开的语句计数达到其允许的最大值时,应用程序仍然能够以某种方式继续工作,而不会产生 sql 错误:

Error Code: 1461 Can’t create more than max_prepared_stmt_count statements

但是在那种模式下,它开始用引号包裹布尔值,导致我所有的麻烦都影响了 BIT(1) 列。

于 2013-10-25T09:32:15.047 回答