EC-CUBEでデータ登録に関するカスタマイズを行っていると、次のエラーが発生することがあります。
An exception occurred while executing a query: SQLSTATE[23000]: Integrity constraint violation: 1062 Duplicate entry '0' for key 'PRIMARY'
既に登録されているプライマリーキー(主キー)と同じ値を重複して登録しようとした、というデータベースのエラーです。エラーメッセージの「Duplicate entry ‘◯◯’ for key ‘△△’」の◯◯が重複した値、△△が重複したキーを表しています。この読み方が分かると原因の切り分けが早くなります。
「Duplicate entry ‘0’ for key ‘PRIMARY’」の意味
重複値が‘0’になっている場合、IDが採番されないまま0でINSERTされています。1件目は0で登録できてしまい、2件目の0で主キー重複になる、という流れです。
EC-CUBEの多くのテーブルは主キーが自動採番(オートインクリメント)されるため通常は意識しませんが、自動採番が効いていない状態になるとこのエラーが出ます。
原因のパターンと対処
1. 自作エンティティ・自作テーブルで自動採番の定義が無い
カスタマイズで独自のエンティティやテーブルを追加した際、エンティティのID定義に自動採番の指定(@ORM\GeneratedValue)が無い、またはテーブル側にAUTO_INCREMENTが付いていないと、IDが0のままINSERTされます。
エンティティの定義とテーブル定義(SHOW CREATE TABLE テーブル名)の両方を確認し、自動採番になっているかを見てください。EC-CUBE本体の既存エンティティ(4系ならsrc/Eccube/Entity/配下)のID定義をひな形にするのが確実です。
2. マスタ系テーブルへのID重複指定
マスタデータ(mtb_で始まるテーブル)は自動採番ではなく、IDを自分で指定して登録する設計です。既存データと同じIDを指定すればそのまま1062になります。登録前に既存のIDを確認し、重複しない値を割り当ててください。
3. データ移行・インポート後に採番カウンタがずれている
サーバー移転やDBインポートの方法によっては、テーブルのAUTO_INCREMENTの現在値がデータの最大IDより小さい状態になることがあります。この場合、新規登録のたびに既存IDとぶつかります。
-- 現在の採番値を確認 SHOW CREATE TABLE dtb_xxx; -- 最大IDより大きい値に設定し直す ALTER TABLE dtb_xxx AUTO_INCREMENT = (最大ID+1);
4. 複合主キーのテーブルに同じ組み合わせを再登録
中間テーブルのように複数カラムの組み合わせが主キーになっているテーブルでは、同じ組み合わせを2回登録すると1062になります(この場合、重複値は ‘3-5’ のようにハイフン区切りで表示されます)。登録前に既存レコードの有無を確認するロジックを入れてください。
調査のポイント
まずエラーメッセージからキー名と重複値を読み取り、スタックトレースやSQLログでどのテーブルへのINSERTかを特定します。あとは上の4パターンのどれに当たるかを、テーブル定義とデータを見て判断する、という順番が最短です。
なお同じ1062でも「for key ‘PRIMARY’」ではなくユニークキー名が表示されている場合は、主キーではなくユニーク制約(メールアドレスの重複など)の違反です。外部キー制約の1452エラーについては別記事で解説しています。
1452 Cannot add or update a child rowの原因と対処法
EC-CUBEに関するお問い合わせ
[重要]現在公式にセキュリティサポートが切れていないPHPは8.1以上、MySQLは8.0以上で、対応しているEC-CUBEバージョンは4.2以上です。古いEC-CUBEを使っている方は適切なタイミングでバージョンアップをご検討ください。