動作は、MySQL セッション変数によって異なりますsql_mode
。接続中に変数を変更し、後で元の値にリセットできます。私のシステムでは、のデフォルト値sql_mode
は次のとおりです。
SELECT @@sql_mode;
-- REAL_AS_FLOAT,PIPES_AS_CONCAT,ANSI_QUOTES,IGNORE_SPACE,ONLY_FULL_GROUP_BY,ANSI,NO_AUTO_VALUE_ON_ZERO,STRICT_ALL_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION,PAD_CHAR_TO_FULL_LENGTH
プログラムでこの結果を解析し、 item を削除しSTRICT_ALL_TABLES
、値を で更新しSET SESSION sql_mode='...'
、ステートメントを実行し、トランザクションの最後に変数をリセットできます。
@ ripper234による編集:
この回答の精神で私が書いたコードは次のとおりです。
private static final disableMysqlStrictMode =
((String)Play.configuration.get("db.url")).contains("mysql://");
...
String originalSqlMode = null;
try {
if (disableMysqlStrictMode) {
// Strip away mysql's "strict mode" for this transaction - in case one of the columns is truncated, we don't want the entire tx to fail
// http://stackoverflow.com/a/10606085/11236
Query query = JPA.em().createNativeQuery("SELECT @@sql_mode;");
originalSqlMode = (String)query.getSingleResult();
String newSqlMode = originalSqlMode
.replace("STRICT_ALL_TABLES", "")
.replace("STRICT_TRANS_TABLES", "")
.replace(",,", ",");
JPA.em().createNativeQuery("SET SESSION sql_mode=?").setParameter(1, newSqlMode).executeUpdate();
}
// Save my entity here
obj.save();
} finally {
if (originalSqlMode != null) {
// Restore original sql_mode
JPA.em().createNativeQuery("SET SESSION sql_mode=?").setParameter(1, originalSqlMode).executeUpdate();
}
}
その気になれば、もっときれいな形に巻くことができます。