バージョン選択

フォーラム

メニュー

オンライン状況

53 人のユーザが現在オンラインです。 (40 人のユーザが フォーラム を参照しています。)
登録ユーザ: 0
ゲスト: 53
もっと...

サイト内検索

質問 > 管理機能 > プラグインで、一対多のエンティティをデータベースに登録する方法について

管理機能

新規スレッドを追加する

スレッド表示 | 新しいものから 前のトピック | 次のトピック | 下へ
投稿者 スレッド
yuy-tank
投稿日時: 2018/1/19 17:01
対応状況: 開発中
一人前
登録日: 2017/11/10
居住地:
投稿: 72
プラグインで、一対多のエンティティをデータベースに登録する方法について
プラグインでエンティティとして、Entity/ChoiceとEntity/ChoiceDetailを作りました。Entity/ChoiceとEntity/ChoiceDetailは一対多の関係にあり、Entity/ChoiceはプロパティにChoiceDetails(\Doctrine\Common\Collections\Collectionのインスタンス)を持ち、これはEntity/ChoiceDetailの配列として機能しています。(本体のEntity/OrderとEntity/OrderDetailと同じです。)
また、Entity/ChoiceとEntity/ChoiceDetailに該当するデータベース上のテーブルは、plg_choiceとplg_choice_detailです。

ちなみに、Entity/ChoiceDetailのプロパティは、
choice_name,
choice_value,
choice_detail_id

のみです。ただ、データベース上では、plg_choice_detailはplg_choiceを参照するためにchoice_idという外部キーを持っています。(一対多の関係であるため)



コントローラーでは、フォームからデータを入力し、Entity/Choiceのインスタンスをそのままデータベースに登録するつもりでした。ところが、フォームから、ChoiceDetails(つまり、複数のEntity/ChoiceDetail)に相当する部分に値(choice_name => "テスト",choice_value => 1)1つだけを入れてサブミットしたところ、次のようなエラーが出ました。

ForeignKeyConstraintViolationException in AbstractMySQLDriver.php line 60:
An exception occurred while executing 'INSERT INTO plg_choice_detail (choice_name, choice_value, choice_detail_id) VALUES (?, ?, ?)' with params ["\u30c6\u30b9\u30c81", "1", null]:
SQLSTATE[23000]: Integrity constraint violation: 1452 Cannot add or update a child row: a foreign key constraint fails (`****データベース名*****`.`plg_choice_detail`, CONSTRAINT `FK_CB044321998666D1` FOREIGN KEY (`choice_id`) REFERENCES `plg_choice` (`choice_id`))

このエラーによると、plg_choice_detailがplg_choiceを参照するために持つ外部キーであるchoice_idにエラーがあるみたいです。また、choice_detail_idがオートインクリメントであるにも関わらず、nullが入れられていることも不可解です。
Entity/ChoiceとEntity/ChoiceDetailを同時にデータベースに登録しようとしているからでしょうか?よろしければ、原因を教えていただきたいです。


ちなみにコントローラーでは、Entity/Choiceのみをデータベースに登録(persist(Choice)およびflush())するため、ChoiceDetailsについては、ymlファイルでcascade['persist']として、自動的にデータベースに登録されるようにしています。
以下に、plg_choice_detailとplg_choiceに該当するdoctrineのymlファイルを以下に示しておきます。





[プラグインコード].Entity.Choice.dcm.yml


[プラグインコード]\Entity\Choice:
type: entity
table: plg_choice
repositoryClass: [プラグインコード]\Repository\ChoiceRepository
id:
id:
type: integer
nullable: false
unsigned: false
id: true
column: choice_id
generator:
strategy: AUTO

fields:
choice_label:
type: text
choice_type:
type: text
choice_blank:
type: text

oneToMany:
ChoiceDetails:
targetEntity: [プラグインコード]\Entity\ChoiceDetail
mappedBy: Choice
orderBy:
id: ASC
cascade: ["persist"]

lifecycleCallbacks: { }










[プラグインコード].Entity.ChoiceDetail.dcm.yml

[プラグインコード]\Entity\ChoiceDetail:
type: entity
table: plg_choice_detail
repositoryClass: [プラグインコード]\Repository\ChoiceDetailRepository
id:
id:
type: integer
nullable: false
unsigned: false
id: true
column: choice_detail_id
generator:
strategy: AUTO

fields:
choice_name:
type: text
choice_value:
type: text

manyToOne:
Choice:
targetEntity: [プラグインコード]\Entity\Choice
inversedBy: ChoiceDetails
joinColumn:
name: choice_detail_id
referencedColumnName: choice_id
nullable: false

lifecycleCallbacks: { }










tsuji
投稿日時: 2018/1/25 14:11
対応状況: −−−
仙人
登録日: 2013/11/19
居住地:
投稿: 958
Re: プラグインで、一対多のエンティティをデータベースに登録する方法について
yuy-tank 様

細かくは見れていませんが、
[プラグインコード].Entity.ChoiceDetail.dcm.yml

上記の下記が間違っているかと思いました。

name: choice_detail_id
referencedColumnName: choice_id


外部キーでつないでいるのであれば、
以下をつなぐ必要があるかと思います。
plg_choice_detail.choice_id
plg_choice.choice_id


これは参考にされている受注情報と受注明細情報が
以下で紐づいているのと同様です。
dtb_order.order_id
dtb_order_detail.order_id


----------------
****************************************
株式会社システムフレンド
辻 拓也(takuya tsuji)
改造専門店・EC-CUBE工房
****************************************

yuy-tank
投稿日時: 2018/1/26 17:24
対応状況: −−−
一人前
登録日: 2017/11/10
居住地:
投稿: 72
Re: プラグインで、一対多のエンティティをデータベースに登録する方法について
返信ありがとうございます。そちらの方を直してみたのですが、どうやらダメみたいです。ちなみにわかりやすく状況を説明すると、ChoiceとChoiceDetailというEntityがあり、フォームでは、ユーザにChoiceの内容を入力させて、ChoiceおよびChoiceDetailをデータベースに登録させます。ChoiceDetailのフォームは、Choiceのフォームに、collectionの形で埋め込んでいます。なので、Choiceをpersist、flushでデータベースに登録すると、ChoiceDetailも自動的にデータベースに登録されるだろうという考えです。しかし、どうやら、flush()のときにエラーになっているようで、ChoiceDetailの外部キーであるchoice_idがnullであるにも関わらず、データベースにChoiceDetailを挿入しようとしているというエラーが出ています。(外部キー制約)

おそらく、Choiceのidがオートインクリメントされる前に、ChoiceDetailをデータベースに登録していると考えられます。なので、Choiceのidのオートインクリメントを優先させるなどの方法が思いつきますが、方法がわかりません。何か解決策があれば教えてください。
468
投稿日時: 2018/1/26 22:34
対応状況: −−−
登録日: 2008/10/26
居住地:
投稿: 3217
Re: プラグインで、一対多のエンティティをデータベースに登録する方法について
/src/Eccube/Controller/Admin/Order/EditController.php 168行目付近に

foreach ($TargetOrder->getOrderDetails() as $OrderDetail) {
    /** @var $OrderDetail \Eccube\Entity\OrderDetail */
    $OrderDetail->setOrder($TargetOrder);
}


のような記述がありますが、setOrder($TargetOrder)のように
子エンティティに親エンティティをセットすれば外部キーのIDがセットされるのではないでしょうか?


----------------
株式会社シロハチ
■ECCUBE2系、3系構築カスタマイズご相談ください。
EC-CUBE3マニュアル
blog

yuy-tank
投稿日時: 2018/2/2 9:51
対応状況: −−−
一人前
登録日: 2017/11/10
居住地:
投稿: 72
Re: プラグインで、一対多のエンティティをデータベースに登録する方法について
返信が遅れて申し訳御座いません。仰る通りに実装すれば無事に解決いたしました。本当にありがとうございました。
スレッド表示 | 新しいものから 前のトピック | 次のトピック | トップ


 



ログイン


EC-CUBE公式 Amazon Payプラグイン

統計情報

総メンバー数は88,722名です
総投稿数は109,953件です

投稿数ランキング

1
seasoft
7367
2
468
3217
3
AMUAMU
2712
4
nanasess
2313
5
umebius
2085
6
yuh
1819
7
h_tanaka
1638
8
red
1570
9
mcontact
1286
10
tsuji
958
11
fukap
907
12
shutta
835
13
tao_s
799
14 ramrun 789
15 karin 689
16 sumida 641
17
homan
633
18 DELIGHT 572
19
patapata
502
20
flealog
485


ネットショップの壺

EC-CUBEインテグレートパートナー

Copyright© EC-CUBE CO.,LTD. All Rights Reserved.