Symfony2使用外键插入两个相关的实体

时间:2014-03-08 17:02:56

标签: symfony insert entity foreign-key-relationship

我有一个Product实体,它具有名为同步设置的选项,存储在另一个表中。产品与使用OneToOne的SynchronizationSetting相关。我坚持使用新产品有点问题。我对SynchronizationSetting的注释看起来像这样:

/**
 * @var \Webrama\ProductBundle\Entity\Product
 *
 * @ORM\OneToOne(targetEntity="Webrama\ProductBundle\Entity\Product")
 * @ORM\JoinColumns({
 *   @ORM\JoinColumn(name="id_product", referencedColumnName="id")
 * })
 * @ORM\Id
 * @ORM\GeneratedValue(strategy="IDENTITY")
 */
private $idProduct;

这是表结构:

CREATE TABLE IF NOT EXISTS `synchronization_setting` (
  `id_product` int(10) unsigned NOT NULL,
  `local` char(1) DEFAULT '0',
  `internet` char(1) DEFAULT '0',
  PRIMARY KEY (`id_product`),
  KEY `id_product` (`id_product`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
ALTER TABLE `synchronization_setting`
  ADD CONSTRAINT `fk_ss_id_product` FOREIGN KEY (`id_product`) REFERENCES `product` (`id`) ON UPDATE CASCADE;

我正在尝试使用此代码插入新产品:

if($request->getMethod() == 'POST')
            {
                $form->handleRequest($request);

                if($form->isValid())
                {
                    $product = $form->getData();

                    $synchronizationSetting = $product->retSynchronizationSetting();
                    $synchronizationSetting->setIdProduct($product);
                    $em->persist($synchronizationSetting);
                    $em->flush();

                    $em->persist($product);
                    $em->flush();

                    $this->get('session')->getFlashBag()->add('notice', $this->get('translator')->trans('save_ok'));

                    return $this->redirect($this->generateUrl("webrama_product_index"));
                }
            }

由于产品在插入时没有相关的同步设置实体,操作失败。错误是:

Webrama \ ProductBundle \ Entity \ SynchronizationSetting类型的实体通过外部实体Webrama \ ProductBundle \ Entity \ Product具有标识,但此实体本身没有标识。您必须在相关实体上调用EntityManager#persist(),并确保在尝试持久化'Webrama \ ProductBundle \ Entity \ SynchronizationSetting'之前生成了标识符。如果生成后插入ID(例如MySQL自动增量或PostgreSQL SERIAL),这意味着您必须在两个持久操作之间调用EntityManager #flush()。

我需要做的是:

  • 在插入产品
  • 之前,使用idProduct创建同步设置实体
  • 将新产品插入数据库

为了做到这一点,我会在保留产品之前插入同步设置表,但我很确定这是使用表单给我的Product和SynchronizationSetting实体更好的方法。问题是:什么方式?

1 个答案:

答案 0 :(得分:1)

我担心解决这个问题的最简单方法就是将product刷新到DB,这样它就会获得它的主键。之后,将synchronization与已刷新的product相关联,并将synchronization本身刷新。