【问题标题】:Doctrine many-to-many join table not populatingDoctrine 多对多连接表未填充
【发布时间】:2016-01-09 04:17:49
【问题描述】:

我有以下教义.ORM.XML 文件。我已经更新了架构,可以查看数据库中的所有表和连接表,并且可以为 ProductOrder 实例化实体。

Products.orm.xml:

<entity name="Product" table="product"
        repository-class="AppBundle\Entity\ProductRepository">

    <many-to-many target-entity="Order" inversed-by="Product" field="orders">
        <join-table name="products_orders">
            <join-columns>
                <join-column name="Product_id" referenced-column-name="id"/>
            </join-columns>
            <inverse-join-columns>
                <join-column name="Orders_id" referenced-column-name="id"/>
            </inverse-join-columns>
        </join-table>
    </many-to-many>
</entity>

Orders.orm.xml:

<entity name="Order" table="order"
        repository-class="AppBundle\Entity\OrderRepository">

   <many-to-many field="products" mapped-by="orders" target-entity="Product" />
</entity>

但是,当我 flush() 将实体添加到数据库时,它只会在 Product/Order 表中单独创建,并且不会在其中生成相应的键记录products_orders 连接表,如我所料。下面是我在控制器中将 flush() 发送到数据库的代码 - 我是否也需要对此进行扩展以处理 products_orders 连接表?

namespace AppBundle\Controller;

use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Symfony\Component\HttpFoundation\Request;
use FOS\RestBundle\Controller\FOSRestController;
use AppBundle\Entity\Product;
use AppBundle\Entity\Order;

class DefaultController extends FOSRestController
{
    /**
     * @Route("/neworder", name="new_order")
     */
    public function newOrderAction(Request $request)
    {
        $order = new Order();
        $em = $this->getDoctrine()->getManager();

        $products = $em->getRepository('AppBundle:Product')
            ->findAllOrderedByName();

        $form = $this->CreateFormBuilder($order)
            ->add('products', 'entity', array(
                'class' => 'AppBundle:Product',
                'choice_label' => 'Description',
            ))
            ->add('Quantity', 'integer')
            ->add('Units', 'text')
            ->add('Save', 'submit', array('label' => 'Create Order'))
            ->getForm();


        $form->handleRequest($request);
        if ($form->isValid()) {
            $em->persist($order);
            $em->flush();
            return $this->redirectToRoute('homepage');
        }

        return $this->render('AppBundle:Default:new.order.form.html.twig', array(
            'form' => $form->createView(),
        ));

    }
}

编辑:

按照 Cerad 的建议,我在下面添加了 addProduct() 函数的地方添加了 Order 实体定义的代码。我还在我的 Product 实体代码中添加了相应的 addOrder() 方法:

namespace AppBundle\Entity;
use Doctrine\Common\Collections\ArrayCollection;

class Order
{
    protected $id;
    public $products;
    public function __construct()
    {
        $this->products = new ArrayCollection();
    }


    public function addProduct($product) {
        $product->addOrder($order);
    }
    #....
}

但是,当我尝试更新学说实体时出现错误:

编译错误:无法重新声明 AppBundle\Entity\Order::addProduct

【问题讨论】:

  • 你必须坚持产品对象而不是订单
  • 假设您以正确的方式填充产品集合,您可以检查如果在多对多产品节点中添加“级联”指令会发生什么,doctrine-orm.readthedocs.org/projects/doctrine-orm/en/latest/…
  • 感谢@SilvioQ,我在产品上添加了&lt;cascade&gt;&lt;cascade-all&gt;&lt;/cascade-all&gt;&lt;/cascade&gt;(就在 部分之前)。我不确定是否也将其添加到订单的 XML 中,这似乎不正确。我已经更新了架构和实体,但不幸的是连接表仍然是空的。有什么我可以更新问题以帮助确定问题的吗?
  • 验证您的产品实体是否包含对订单实体的引用,反之亦然。忘记将两者交叉链接的情况并不少见。如果您不确定,请更新您的问题并在 handleRequest 之前显示控制器代码。
  • 感谢@Cerad - 我已将我的完整控制器添加到问题的末尾。我只是要再次更新它以添加我的 Order 实体的一部分,以防你提到我可能会丢失?

标签: mysql xml symfony doctrine-orm


【解决方案1】:

我猜你的 Order::addProduct 看起来像这样:

class Order {
  addProduct($product) {
    $this->products[] = $product;

如果是这样,那么您就没有告诉产品有关新订单的信息。你需要添加

    $product->addOrder($order);

这将完成您的两种方式引用,并且应该允许坚持按预期工作。如果你已经有了上面的代码,那就有别的问题了。

【讨论】:

  • 谢谢,我认为你是对的——尽管我使用的是带有自动生成的 getter/setter 的学说生成的实体。你提到的addProduct 方法我根本没有。我是否也需要向我的 Product 实体添加相应的 addOrder 方法?我以为我在 __construct 处理了这个问题?
  • 发布处理产品的订单代码。您应该有某种添加或设置产品。同样,您的 Product 实体需要某种设置/添加顺序。顺便说一句,在产品和订单之间存在多对多关系有点不寻常。通常,您会有一个 OrderLine 实体,它允许为给定产品设置数量。
  • 在尝试添加您提到的 addProduct 函数后,我已更新我的问题以包含 Order 类 - 以及我遇到的教义错误 - 提前致谢
  • 错误信息表明 Order 类中已经存在 addProduct 方法。
  • 谢谢 - 我做到了!现在修复它,我得到了Catchable Fatal Error: "Arguement 1 passed ...must be of the type array 的“真实”错误。但是,在我上面的代码中,我将它定义为数组 - 这是否也需要在 orm.xml 中以某种方式成为数组?
猜你喜欢
  • 2015-09-27
  • 2016-06-13
  • 2019-02-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-04-07
相关资源
最近更新 更多