【问题标题】:Issue with ManyToMany relationship多对多关系的问题
【发布时间】:2015-05-01 16:46:50
【问题描述】:

我有 2 个实体。

一个包和一个 StockItem。

Package 可以有多个 StockItem,StockItem 可以属于 Many packages。 ManyToMany 似乎最合适。

当我尝试将 2 个相同的库存商品添加到一个包裹中时,会出现此问题,我们会遇到 Integraty 违规:

{"code":500,"message":"An exception occurred while executing 'INSERT INTO StockItem_In_Package (package_id, stockitem_id) VALUES (?, ?)' with params [4, 1]:\n\nSQLSTATE[23000]: Integrity constraint violation: 1062 Duplicate entry '4-1' for key 'PRIMARY'"}

由于 Package(id 4),与 stockItem 1 创建 2 个关系。

4-1 和 4-1

有没有可能以任何方式解决这个问题? 是否可以将名为 id 的第三列添加到 ManyToMany 表,或者添加一个名为 ItemCountInPackage 的列,并在将其添加到包中时将其增加一?什么是最好的解决方案。

封装实体,只插入相关代码:

/**
 * Package
 *
 * @ORM\Table()
 * @ORM\Entity(repositoryClass="IHEnterprise\LogisticsBundle\Entity\PackageRepository")
 * @ORM\HasLifecycleCallbacks
 *
 * @ExclusionPolicy("all")
 *
 */
class Package
{

    /**
     * @var integer
     *
     * @ORM\Column(name="id", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     * @Expose
     */
    private $id;

    /**
     * @ORM\ManyToMany(targetEntity="IHEnterprise\LogisticsBundle\Entity\StockItem", cascade={"all"}, indexBy="package_id")
     * @ORM\JoinTable(name="StockItem_In_Package",
     *      joinColumns={@ORM\JoinColumn(name="package_id", referencedColumnName="id")},
     *      inverseJoinColumns={@ORM\JoinColumn(name="stockitem_id", referencedColumnName="id")}
     *      )
     * @Expose
     * @Assert\NotNull()
     **/
    private $stockItems;
}

StockItem 实体,只插入相关代码:

/**
 * StockItem
 *
 * @ORM\Table()
 * @ORM\Entity(repositoryClass="IHEnterprise\LogisticsBundle\Entity\StockItemRepository")
 * @ORM\HasLifecycleCallbacks
 *
 * @ExclusionPolicy("all")
 *
 */
class StockItem
{
    /**
     * @var integer
     *
     * @ORM\Column(name="id", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     * @Expose
     */
    private $id;
}

我不需要跟踪哪些 StockItems 属于哪些包裹,只需要跟踪哪些包裹包含哪些 stockitems。

【问题讨论】:

    标签: symfony doctrine entity


    【解决方案1】:

    您不能在多对多关系中添加第三列。所以你不能在一个包中拥有两次相同的 StockItem。

    要在一个包中包含多个相同的 StockItem,您必须创建具有唯一 ID 的第三个实体,以及与 StockItem 和 Package 的 ManyToOne 关系(以及 StockItem & Package 中的 OneToMany 关系与您的第三个实体)。

    【讨论】:

    • 我加倍。我前段时间也做过。
    【解决方案2】:

    您似乎正在尝试将已在数据库中的项目作为新记录插入。为防止出现此类错误,请执行以下操作:

    /**
     * @desc Add only new items to a single package 
     * @param \AcmeBundle\Entity\Package $package
     * @param ArrayCollection<StockItem> $stockItems
     */
    public function addStockItemsAction(Package $package, $stockItems) {
        foreach ($stockItems as $stockItem) {
            if ($package->contains($stockItem) === false) {
                $package->addStockItem($stockItem);
            }
        }    
    }
    

    【讨论】:

    • 是的,因为应该有 2 个
    • 哼,不可行。关系必须是唯一的。您可以克隆您的实体,以便您有一个副本,但您不能添加两次相同的关系。这在技术上是不可行的并且在概念上是错误的:/我可以知道你为什么需要这样的东西。必须有另一种方法。
    • 哦,我想我知道你想要什么。您这样做是因为您想处理单件商品的库存数量吗?
    • 然后,您应该在 StockItem 实体上添加一个名为“数量”的列并更新该值而不是添加删除对象。
    猜你喜欢
    • 2011-01-05
    • 1970-01-01
    • 2020-04-10
    • 2021-09-14
    • 2015-07-09
    • 2014-11-11
    • 2020-04-04
    • 1970-01-01
    相关资源
    最近更新 更多