通过关系***找到了一个新实体,该实体未配置为级联持久操作

时间:2017-01-23 09:59:32

标签: php symfony symfony-forms silex

我正在尝试制作一个简单的两步形式:

  1. 第一步:选择目标产品
  2. 第二步:查看产品价格,输入订单标题并下订单。
  3. 在Silex中使用Symfony Form Component,我收到此错误:

      

    通过“订单 产品”关系找到了一个新实体,该关系未配置为级联实体的持久操作:'产品

    实体:

    1 - 产品

    Class Product {
    
        OneToMany(targetEntity="Order", mappedBy="product", cascade={"persist","remove"})
        private $orders;
    
        public function __construct() {
            $this->orders = new ArrayCollection()
        }
    }
    

    2 - 订单

    Class Order {
    
        ManyToOne(targetEntity="Product", inversedBy="orders")
        private $product;
    }
    

    表单类型:

    1 - OrderProductType (选择目标产品)

    Class OrderProductType extends AbstractType
    {
        public function configureOptions(OptionsResolver $resolver) {
            $resolver->setDefaults(array(
                'data_class' => Order::class,
            ));
        }
    
        public function buildForm($builder) {
            $builder
                ->add('product', EntityType::class, array(
                    'class'              => Product::class,
                )->getForm();
    
            return $form;
        }
    }
    

    2 - OrderType

    Class OrderType extends AbstractType
    {
        public function configureOptions(OptionsResolver $resolver) {
            $resolver->setDefaults(array(
                'data_class' => Order::class,
            ));
        }
    
        public function buildForm($builder) {
            $builder
                ->add('product_price', TextType::class, array(
                    'data'               => $order->getProduct()->getPrice(),
                    'mapped'             => false,
                    'disabled'           => true,
                ))
                ->add('title', TextType::class)->getForm();
    
            return $form;
        }
    }
    

    控制器:

    1 - 设置产品

    public function setProduct(Application $app, Request $request)
    {
        $order = new Order();
    
        $form = $app['form.factory']->create(OrderProductType::class, $order);
        $form->handleRequest($request);
    
        if ($form->isSubmitted() && $form->isValid()) {
    
            $order = $form->getData();
            $app['session']->set('dummyOrder', $order);
    
            return $app->redirect($app['url_generator']->generate('orders_add'));
    
        }
    
        return $app['twig']->render('orders/add.html.twig', array(
            'form' => $form->createView(),
        ));
    }
    

    2 - 添加订单

    public function add(Application $app, Request $request)
    {
        $order = $app['session']->get('dummyOrder');
    
        $form = $app['form.factory']->create(OrderType::class, $order);
        $form->handleRequest($request);
    
        if ($form->isSubmitted() && $form->isValid()) {
    
            $order = $form->getData();
    
            $app['em']->persist($order);
            $app['em']->flush();
    
            $app['session']->remove('dummyOrder');
    
            return $app->redirect($app['url_generator']->generate('orders_show', ['id' => $order->getId()]));
    
        }
    
        return $app['twig']->render('orders/add.html.twig', array(
            'form' => $form->createView(),
        ));
    }
    

    尝试:

    到目前为止我尝试了什么:

    1. 尝试用redirect替换sub-request forward,传递json编码的product实体,但没有成功。
    2. 尝试将产品 - 订单关系从BiDirectional切换到UniDirectional但没有成功。
    3. 尝试合并product但没有成功。
    4. 试图在第一个表单步骤中保留order并在第二步合并,但没有成功。

2 个答案:

答案 0 :(得分:1)

问题在于订单对象的序列化。

当您按$order序列化$app['session']->set('dummyOrder', $order);,然后在$order = $app['session']->get('dummyOrder');对其进行反序列化时,Product对象不再由Doctrine管理。

这就是为什么当您尝试在$order保存add()时出现错误。

对于你的情况,我建议两种解决方案。

  1. 将订单保存到数据库(带有一些标记,如'临时'),并将订单ID传递给会话。然后使用Doctirne从DB检索订单。
  2. setProduct()中的会话设置替换为

    $app['session']->set('dummyOrderProductId', $order->getProduct()->getId());
    

    然后替换add()(伪代码)

    中的顺序检索
    $order = new Order();
    $product = $em->getRepository(Product::class)->findOneById($app['session']->get('dummyOrderProductId'))
    $order->setProduct($product);
    
    1. $order的{​​{1}}读取产品ID,并将其传递给会话。然后在setProduct()中再次创建新的$order,从数据库中读取产品并将其添加到add()
    2. 在这两种情况下,您都会通过Doctrine管理$order并避免出现问题。

答案 1 :(得分:0)

首先,请提供完整的代码。这不是有效的PHP代码:

OneToMany(targetEntity="Order", mappedBy="product", cascade={"persist","remove"})
private $orders;

缺少有关列的信息。

但是谈到这个问题,你似乎有一个错误的Doctrine映射。在这种情况下,您应该在cascade实体中有Order选项。在产品方面,它不是真正的映射,它只是对映射的引用(mappedBy="product"

* @ORM\ManyToOne(targetEntity="Product", inversedBy="orders", cascade={"persist","remove"})