Php 多人关系学说

Php 多人关系学说,php,doctrine-orm,zend-framework2,Php,Doctrine Orm,Zend Framework2,非常简单(我想!),我有一个发票实体和一个优惠券实体。发票上可以有许多优惠券。相反,优惠券可以用于许多发票 不包括getter/setter: 发票 namespace Application\Entity; use Doctrine\Common\Collections\ArrayCollection; use Doctrine\ORM\Mapping as ORM; /** * @ORM\Entity * @ORM\Table(name="invoices") */ class I

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

不包括getter/setter:

发票

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;

}
当我运行helper工具生成模式时,正如预期的那样,它会创建一个包含优惠券id、发票id(完美)的联接表invoices\u优惠券

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

看来我做不到:

// 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();
我得到这个错误:

通过关系\应用程序\实体\发票#优惠券找到了一个新实体,该优惠券未配置为级联实体的持久化操作:(优惠券到字符串)。要解决此问题,请对此未知实体显式调用EntityManager#persist(),或在映射中配置cascade persist此关联,例如@ManyToOne(..,cascade={\u002persist\u0022})

现在,我不想让它创造新的优惠券;为什么要这样做?优惠券已经存在,它是从ER加载的,并且正在添加到现有实体中

如果我按照错误消息所说的做,它会尝试将新优惠券复制到优惠券表中


谢谢您的建议。

条令\ORM\EntityManager::update()
似乎不存在。在addCouncil()调用和flush()调用之间不必执行任何操作

如果简化代码并不能神奇地修复它,那么下一步应该是确保
$couponMapper->getEntityManager()===$invoiceMapper->getEntityManager()

不清楚如何实例化这些映射器类,但重要的是要了解每个EntityManager都为实体维护自己的内部标识映射。因此,如果您的DIC出于某种原因正在实例化两个不同的EMs(每个映射器一个),那么$invoiceMapper的EM不会将$优惠券识别为托管实体

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


但考虑到您提供的代码,我能想到的最明显的事情就是拥有两个不同的EntityManager。

为什么要合并?这两个映射程序共享同一个实体管理器吗?我无意中读到了merge的文档。相反,使用update会产生这个可怕的错误
通过关系\u0027Application\\entity\\Invoice\u0027找到一个新实体,该关系未配置为级联实体HOST5的持久化操作。要解决此问题,请对此未知实体显式调用EntityManager#persist(),或者在映射中配置cascade persist此关联,例如@ManyTone(..,cascade={\u002persist\u0022})。“,
您是对的。有人禁用了共享;现在来深入了解为什么会这样做+