繁体   English   中英

学说多对多关系

[英]Doctrine ManyToMany Relationship

非常简单(我想!),我有一个发票实体和一个优惠券实体。 发票上可以应用许多优惠券。 相反,优惠券可用于许多发票。

不包括吸气剂/吸气剂:

发票

namespace Application\Entity;

use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\ORM\Mapping as ORM;

/**
 * @ORM\Entity
 * @ORM\Table(name="invoices")
 */
class Invoice
    /**
     * @ORM\ManyToMany(targetEntity="Application\Entity\Coupon")
     * @ORM\JoinTable(name="invoices_coupons")
     */
    protected $coupons;

    public function addCoupon( Coupon $coupon ){
        if( !$this->coupons )
            $this->coupons = new ArrayCollection();

        $this->coupons->add($coupon);
    }
}

优惠券

/**
 * @ORM\Entity
 * @ORM\Table(name="coupons", indexes={@ORM\Index(name="code_idx", columns={"code"})})
 */
class Coupon implements CandidateInterface
{
    /**
     * @var \Ramsey\Uuid\Uuid
     *
     * @ORM\Id
     * @ORM\Column(type="uuid")
     * @ORM\GeneratedValue(strategy="CUSTOM")
     * @ORM\CustomIdGenerator(class="Ramsey\Uuid\Doctrine\UuidGenerator")
     */
    protected $id;

    /**
     * @var string
     * @ORM\Column(type="string", length=32, unique=true)
     */
    protected $code;

}

当我按预期运行助手工具以生成架构时,它会创建一个联接表invoices_coupons,其中包含coupon_id,invoice_id(完美)。

因此,在代码中,我有一个现有的存储发票和一个类似的现有优惠券。

看来我做不到:

// runs a QB to return the coupon, returns a Coupon Entity
$coupon = $couponMapper->getActiveByCode('SAVEBIG'); 
$invoice->addCoupon( $coupon );
$invoiceMapper->getEntityManager()->update( $invoice );
$invoiceMapper->getEntityManager()->flush();

我收到此错误:

通过关系\\ Application \\ Entity \\ Invoice#coupons找到了一个新实体,该实体未配置为级联实体的持久化操作:(优惠券toString)。 解决此问题的方法:在此未知实体上显式调用EntityManager#persist()或配置级联,将该关联保留在映射中,例如@ManyToOne(..,cascade = {\\ u0022persist \\ u0022})。

现在,我不希望它创建新的优惠券。 为什么要尝试这个? 优惠券已存在,已从ER加载,并已添加到现有实体。

如果我按照错误消息的指示进行操作,它将尝试将新的优惠券复制到优惠券表中。

感谢您的建议。

Doctrine\\ORM\\EntityManager::update()似乎不存在。 在addCoupon()调用和flush()调用之间,您不必做任何事情。

如果简化代码并不能解决问题,那么下一步应该是确保$couponMapper->getEntityManager() === $invoiceMapper->getEntityManager()

目前尚不清楚如何实例化这些映射器类,但是了解每个EntityManager维护自己的实体内部身份映射非常重要。 因此,如果您的DIC由于某种原因实例化了两个不同的EM(每个Mapper一个),那么$ invoiceMapper的EM不会将$ coupon识别为托管实体。

那样的话将很奇怪。 假设您使用的是ZF2的ServiceManager,则必须明确将EntityManger服务设置为不共享。

但是考虑到您提供的代码,以某种方式拥有两个不同的EntityManager是最明显的事情。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM