概要
ASP.NET CoreでDocker上で稼働しているMySQLをいろいろこねくり回してるんですが
タイトルのエラーが出て辛かったので対応手順のメモです。
また、本事象の回避自体はできましたが根本原因は別にありました。
本事象回避後、前回の記事のエラーが発生し対策を実施したところ今回のエラーも同時に回避可能でした。
(本記事と前回の記事のあとDBを再作成しており今回設定する設定値が初期化されたにもかかわらずエラーが発生しないことが判明したため)
目次
環境
- MacOS Mojave Version 10.14.3
- .Net Core SDK Version 2.2.104
- Docker Version 18.09.2
- Docker image : MySQL 5.7(公式)
参考サイト様
- https://sawara.me/mysql/1239/ 🔗
- https://dev.mysql.com/doc/refman/5.7/en/sql-mode.html 🔗
- https://github.com/aspnet/AspNetCore/issues/1937 🔗
事象
Login
画面に遷移し外部認証(Twitter)を実施。
その後、メールアドレスを登録するが登録した際に以下のエラーが発生する。
An unhandled exception occurred while processing the request.
MySqlException: Field 'Id' doesn't have a default value
MySqlConnector.Core.ServerSession.TryAsyncContinuation(Task<ArraySegment<byte>> task) in C:\projects\mysqlconnector\src\MySqlConnector\Core\ServerSession.cs, line 1252
MySqlException: Field 'Id' doesn't have a default value
MySql.Data.MySqlClient.MySqlDataReader.ActivateResultSet(ResultSet resultSet) in C:\projects\mysqlconnector\src\MySqlConnector\MySql.Data.MySqlClient\MySqlDataReader.cs, line 81
DbUpdateException: An error occurred while updating the entries. See the inner exception for details.
Microsoft.EntityFrameworkCore.Update.ReaderModificationCommandBatch.ExecuteAsync(IRelationalConnection connection, CancellationToken cancellationToken)
原因
外部認証(Twitter)を実行した際に独自のClaimをDBに登録している。
DBにデータを登録する際の動作としてAspNetUserClaims
テーブルにデータを登録する。
該当テーブルはプライマリーキーにId
カラムが存在するのだが該当のカラムはEntityFrameworkのコード上、自動採番のカラムとなっている。
根本原因としてはDBテーブルの該当カラムにauto_increment
属性が付与されておらず自動採番がされなかったため主キーが抜け落ちてる状態となったためである。
しかし、この時点ではDBの設定である自動採番タイミングがEF側のコードと一致していないことが原因と疑われたためDB設定の変更を実施した。
対策
MySQLのsql_mode
を変更します。
DockerのMySQL公式イメージをそのまま使用していたため設定値を全く変更していない状態でした。
sql_mode
の確認
下記コマンドにて現在のsql_mode
を確認します。
mysql> SHOW GLOBAL VARIABLES LIKE 'sql_mode';
+---------------+-------------------------------------------------------------------------------------------------------------------------------------------+
| Variable_name | Value |
+---------------+-------------------------------------------------------------------------------------------------------------------------------------------+
| sql_mode | ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION |
+---------------+-------------------------------------------------------------------------------------------------------------------------------------------+
sql_mode
の変更
設定を変更する値についてはこちらの記事が大変わかりやすく参考になりました。
https://sawara.me/mysql/1239/ 🔗
本件ではSTRICT_TRANS_TABLES
が該当すると思われるのでSTRICT_TRANS_TABLES
を設定値から外して下記のように変更します。
mysql> SET GLOBAL sql_mode = "ONLY_FULL_GROUP_BY,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION";
Query OK, 0 rows affected, 1 warning (0.00 sec)
結果確認
上記設定反映後、ログインを実施しようとすると本事象は回避できていますが前回記事のエラーが発生しました。
雑感
送別会のあと酔っ払いながらこのエラーと格闘したんですが結局根本原因別だったって言う落ち。
酔っ払いなんだからさっさと寝ればよかった。