【问题标题】:symfony2 doctrine how to update OneToMany entities after persist?symfony2 原则坚持后如何更新 OneToMany 实体?
【发布时间】:2015-02-06 07:51:36
【问题描述】:

我得到了两个实体。 这是第一个有 OneToMany 关系的:

class MarketMain
{
    /**
     * @var integer
     *
     * @ORM\Column(name="id", type="bigint", nullable=false)
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="IDENTITY")
     */
    private $id;

    /**
     * @var \Doctrine\Common\Collections\Collection
     *
     * @ORM\OneToMany(targetEntity="\Acme\CMSBundle\Entity\MarketLanguage", mappedBy="marketMain", indexBy="langId", cascade="all", orphanRemoval=true, fetch="EXTRA_LAZY")
     */
    private $marketLanguage;
}

这是第二个有反转多对一关系的:

class MarketLanguage
{
    /**
     * @var integer
     *
     * @ORM\Column(name="market_id", type="integer", nullable=false)
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="NONE")
     */
    private $marketId = 0;

    /**
     * @var integer
     *
     * @ORM\Id
     * @ORM\Column(name="lang_id", type="integer", nullable=false)
     */
    private $langId = 1;

    /**
     * @var string
     *
     * @ORM\Column(name="name", type="string", length=200, nullable=true)
     */
    private $name;

    /**
     * @var \Acme\CMSBundle\Entity\MarketMain
     *
     * @ORM\ManyToOne(targetEntity="\Acme\CMSBundle\Entity\MarketMain", inversedBy="marketLanguage")
     * @ORM\JoinColumn(name="market_id", referencedColumnName="id")
     */
    private $marketMain;
}

我想像这样保存实体:

$em = $this->getDoctrine()->getManager();

$marketMain = new MarketMain();
$marketLanguage = new ArrayCollection();
$marketLanguage->set(1,new MarketLanguage());
$marketLanguage->set(2,new MarketLanguage());
$marketLanguage->set(3,new MarketLanguage());
$marketMain->setMarketLanguage($marketLanguage);

foreach ($marketMain->getMarketLanguage() as $market_language)
{
$market_language->setMarketMain($marketMain);
}
$em->persist($marketMain);
$em->flush();

foreach ($marketMain->getMarketLanguage() as $market_language)
{
   $market_language->setName("Default name for MarketMain entity id:".$marketMain->getId());
}
$em->flush();

但在第二次刷新后,我的 MarketLanguage 实体没有更新,在学说查询日志中,我看到 MarketLanguage 实体在与 MarketMain 保持后没有关系。请不要说我必须在持久化之前设置 MarketLanguage 名称,因为我必须将刷新的 ID 添加到该名称。

这是在第二次刷新中执行更新的查询(来自学说日志):

"START TRANSACTION" [] []
UPDATE market_language SET name = ? WHERE market_id = ? AND lang_id = ? ["Default name for MarketMain entity 15",0,"1"] []
"COMMIT" [] []

【问题讨论】:

  • 你说MargetLanguage实体不更新,那为什么日志文件中有UPDATE语句?

标签: php symfony doctrine-orm


【解决方案1】:

看起来问题是由于 MarketLanguage ID 已修复,因为:

private $marketId = 0;

请在没有= 0的情况下重试

编辑:由于您使用“无”ID 生成策略,您必须手动为您的 MarketLanguage 实体分配 ID。见doc

【讨论】:

  • 如果这样做,我会收到此错误:Acme\CMSBundle\Entity\MarketLanguage 类型的实体缺少为字段“marketId”分配的 ID。此实体的标识符生成策略要求在调用 EntityManager#persist() 之前填充 ID 字段。如果您想要自动生成标识符,则需要相应地调整元数据映射。
  • 那么就很明显了。为什么你们都指定GeneratedValue 和策略“NONE”? Fom doc: NONE is the same as leaving off the @GeneratedValue entirely. 所以你应该两者都做:使用另一种策略并删除 $marketId 上的默认值
  • @DonatasVeikutis 我看到您正在为MarketLanguage 使用复合键。看起来$marketId 将是父MarketMain 的ID。如果是这样,您的用例类似于this
  • 但是,我建议您删除MarketLanguage 中的复合键:仅使用$langId 作为ID,并将$marketId 替换为普通的@ManyToOne。这样您就不必手动管理复合 ID。
【解决方案2】:

$marketMain = new MarketMain();您正在创建新实例,所以

$marketMain->getMarketLanguage() 

将返回空数组,也许您应该从数据库中查询所有 MarketLanguages 然后将它们分配给 MarketMain ?

$langs = $em->getRepositiory('Bundle:MarketLanguage')->findAll()
foreach ($langs as $market_language)
  {
     $market_language->setMarketMain($marketMain);
  }
$em->persist($marketMain);
$em->flush();

编辑:

所以试试这个:

$ml1 = new MarketLanguage();
$ml2 = new MarketLanguage();
$ml3 = new MarketLanguage();
$marketLanguage->set(1,$ml1);
$marketLanguage->set(2,$ml2);
$marketLanguage->set(3,$ml3);
$marketMain->setMarketLanguage($marketLanguage);

foreach ($marketMain->getMarketLanguage() as $market_language)
{
$market_language->setMarketMain($marketMain);
}
$em->persist($marketMain);

$em->persist($ml1);
$em->persist($ml2);
$em->persist($ml3);
$em->flush();

【讨论】:

  • 抱歉,我没有显示我创建 MarketLanguage 实体的错误,我更新了我的问题
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-12-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-06-25
相关资源
最近更新 更多