1

テーブル商品があります。これらのテーブルのアイテムは、 cart_itemorder_itemshipping_itemなどのテーブルで参照されています。

これらの参照はすべてオプションです(product_idはこれらのテーブルでnull許容に設定されています)。

製品を削除し、他のテーブルのレコードを保持する方法が必要です。私が考えることができる1つの方法は、これらすべてのテーブルに移動し、product_idをnullに設定してから、製品テーブルに戻って削除することです。ただし、製品を参照しているすべてのテーブルを知っているとは限らないため(他の多くのバンドルには、この製品を参照しているエンティティを含めることができます)、ループしてnullを設定するこれらすべての関連付けを知る方法はありますか?

(または、おそらくもっと良い方法がありますか?)

PS:これはショッピングカートであり、所有者は期限切れの製品を削除してクリーンアップしたいと思うかもしれませんが、注文されて出荷されたアイテムの場合は、記録を保持する必要があります。

編集1:

これは、OrderItemエンティティの製品参照の定義です。

/**
 * @var \Product
 *
 * @ORM\ManyToOne(targetEntity="Product")
 * @ORM\JoinColumns({
 *   @ORM\JoinColumn(name="product_id", referencedColumnName="id")
 * })
 */
private $product;

私が得ているエラー:

PDOException:SQLSTATE [23000]:整合性制約違反:1451親行を削除または更新できません:外部キー制約が失敗します(testorder_item、C ONSTRAINT fk_order_item_product1FOREIGN KEY(product_id)REFERENCES productid)ON DELETE NO ACTION ON UPDATE NO ACTION)

Edit2:

最初にonupdate="SET NULL"をorder_itemエンティティに設定しましたが、それで十分だと思いましたが、そうではありませんでした。

/**
 * @var \Product
 *
 * @ORM\ManyToOne(targetEntity="Product")
 * @ORM\JoinColumns({
 *   @ORM\JoinColumn(name="product_id", referencedColumnName="id", nullable=true, onDelete="SET NULL")
 * })
 */
private $product;

その後、dbスキーマも更新する必要がありました。

4

1 に答える 1

3

product所有エンティティと他のエンティティの間に適切な関係が設定されていると仮定すると、たとえばcart_item、foreign_keyが必要な場合、必要な動作がDoctrine2のデフォルトになります。

こちらのマニュアルをご覧ください

User例として、エンティティとそれに対応するエンティティの削除を示していますComments

$user = $em->find('User', $deleteUserId);

foreach ($user->getAuthoredComments() AS $comment) {
    $em->remove($comment);
}
$em->remove($user);
$em->flush();

例は次のように述べています。

作成されたすべてのコメントをループしない場合、Doctrineは外部キーをNULLに設定するためにのみUPDATEステートメントを使用し、flush()-操作中にユーザーのみがデータベースから削除されます。

これは、あなたの場合、あなたが実際にその振る舞いを望んでいることを私に示唆しています。したがって、productエンティティを削除するだけで、Doctrine 2は、その製品に属するforeign_keyを持つ他のすべてのエンティティを自動的に検索し、次のように設定します。NULL

編集
エラーメッセージは、productエンティティを削除しようとしても、foreign_keysがまだ存在していることを示しています。つまり、Doctrineによって正しくnullに設定されていません。特にエンティティの関係にcascadeプロパティを追加する必要があります。remove次のようになります。

<?php
class Product
{
    //...
    /**
     * Bidirectional - One-To-Many (INVERSE SIDE)
     *
     * @OneToMany(targetEntity="Cart", mappedBy="product", cascade={"remove"})
     */
    private $carts;
    //...
}
于 2013-03-27T09:16:45.430 に答える