【问题标题】:Symfony 3 expected "Doctrine\Common\Collections\ArrayCollection" given ... when using OneToManySymfony 3 预期“Doctrine\Common\Collections\ArrayCollection”在使用 OneToMany 时给出...
【发布时间】:2017-03-29 21:03:08
【问题描述】:

我有这个错误的问题:

Expected argument of type "AppBundle\Entity\BusVehiclesAmenities", "Doctrine\Common\Collections\ArrayCollection" given

编辑 3

经过几个 cmets,我应用了建议并且错误现在消失了(从公共汽车设施实体中删除 ArrayCollection,从控制器中删除设置公共汽车设施实体并删除所有映射实体上的 ORM 连接列)

现在我有这个错误:

The association AppBundle\Entity\BusVehiclesAmenities#bus refers to the inverse side field AppBundle\Entity\BusVehicles#busVehiclesAmenities which does not exist.

映射实体

公交车:

/* @ORM\OneToMany(
     *     targetEntity="BusVehiclesAmenities",
     *     mappedBy="bus",
     *     fetch="EXTRA_LAZY",
     *     orphanRemoval=true,
     *     cascade={"persist"}

     * )
     *
     */

    private $busVehiclesAmenities;

公共汽车设施实体:

private $bus;

    /**
     *
     * @ORM\ManyToOne(targetEntity="Amenities", inversedBy="amenities")
     * @ORM\JoinColumn(name="amenities_id", referencedColumnName="id")
     *
     */

我正在使用表单集合来创建 OneToMany 关系。问题是当我添加新数据时出现此错误。

有人知道问题出在哪里吗?

代码: 总线实体(父)

/**
     * @ORM\OneToMany(targetEntity="BusVehiclesAmenities", mappedBy="bus", cascade={"persist", "remove"}, fetch="EAGER", orphanRemoval=true)
     * @ORM\JoinColumn(name="bus_id", referencedColumnName="id", onDelete="CASCADE")
     *
     */

private $busVehiclesAmenities;

    public function __construct()
    {

        $this->busVehiclesAmenities = new ArrayCollection();
    }


    /**
     * Get id
     *
     * @return integer
     */
    public function getId()
    {
        return $this->id;
    }

    /**
     * Add busVehiclesAmenities
     *
     * @param \AppBundle\Entity\BusVehiclesAmenities busVehiclesAmenities
     * @return BusVehicles
     */
    public function addBusVehiclesAmenities(BusVehiclesAmenities $busVehiclesAmenities)
    {

         if ($this->busVehiclesAmenities->contains($busVehiclesAmenities)) {
             return;
         }
        $this->busVehiclesAmenities->add($busVehiclesAmenities);
        $busVehiclesAmenities->addBus($this);

        return $this;
    }

    /**
     * Set busVehiclesAmenities
     *
     * @param \AppBundle\Entity\BusVehiclesAmenities busVehiclesAmenities
     * @return BusVehicles
     */
    public function setBusVehiclesAmenities(BusVehiclesAmenities $busVehiclesAmenities)
    {

         $this->busVehiclesAmenities = $busVehiclesAmenities;

        return $this;
    }

    /**
     * Remove busVehiclesAmenities
     *
     * @param \AppBundle\Entity\BusVehiclesAmenities $busVehiclesAmenities
     * @return BusVehicles
     */
    public function removeBusVehiclesAmenities(BusVehiclesAmenities $busVehiclesAmenities)
    {
        if (!$this->busVehiclesAmenities->contains($busVehiclesAmenities)) {
            return;
        }
        $this->busVehiclesAmenities->removeElement($busVehiclesAmenities);
        $busVehiclesAmenities->removeBus($this);

        return $this;



    }

设施实体(儿童)

/**
     *
     * @ORM\ManyToOne(targetEntity="BusVehicles", inversedBy="busVehiclesAmenities")
     * @ORM\JoinColumn(name="bus_id", referencedColumnName="id")
     *
     */
    private $bus;

    public function __construct()
    {
        $this->bus = new ArrayCollection();
    }


    /**
     * Get id
     *
     * @return integer
     */
    public function getId()
    {
        return $this->id;
    }


    /**
     * @param BusVehicles $busVehicles
     */

    public function addBus(BusVehicles $busVehicles)
    {
        if ($this->bus->contains($busVehicles)) {
            return;
        }
        $this->bus->add($busVehicles);
        $busVehicles->addBusVehiclesAmenities($this);
    }

    /**
     * @param BusVehicles $busVehicles
     */
    public function removeBus(BusVehicles $busVehicles)
    {
        if (!$this->bus->contains($busVehicles)) {
            return;
        }
        $this->bus->removeElement($busVehicles);
        $busVehicles->removeBusVehiclesAmenities($this);
    }

编辑 1:

我从 BusVehiclesAmenitites 实体中删除了 ArrayCollection,但我在提交表单时仍然遇到同样的错误。

编辑 2:

添加表单

BusVehicles 表单类型

<?php

namespace AdminBundle\Form\Type;

use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
use Symfony\Component\Form\Extension\Core\Type\CollectionType;




class BusVehiclesType extends AbstractType
{
    /**
     * {@inheritdoc}
     */
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder->add('licencePlate')
            ->add('chassisNumber')
            ->add('manufacturer')
            ->add('busVehiclesAmenities', CollectionType::class, array(
                'entry_type'   => BusVehiclesAmenitiesType::class,
                'prototype' => true,
                'allow_add' => true,
                'allow_delete' => true,
                'by_reference' => false,
            ));
    }

    /**
     * {@inheritdoc}
     */
    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setDefaults(array(
            'data_class' => 'AppBundle\Entity\BusVehicles',
            'cascade_validation' => true,

        ));
    }

    /**
     * {@inheritdoc}
     */
    public function getBlockPrefix()
    {
        return 'adminbundle_busvehicles';
    }


}

BusVehiclesAmenities 表单类型

    <?php

namespace AdminBundle\Form\Type;

use Symfony\Bridge\Doctrine\Form\Type\EntityType;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\NumberType;
use Symfony\Component\Form\FormBuilderInterface;
use AppBundle\Entity\BusVehiclesAmenities;
use Symfony\Component\OptionsResolver\OptionsResolver;


class BusVehiclesAmenitiesType extends AbstractType
{
    /**
     * {@inheritdoc}
     */
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('price', NumberType::class, array(

            ))
            ->add('amenities', EntityType::class, array(
                'class' =>'AppBundle:Amenities',
                'choice_label' => 'name',
            ))

        ;

    }

    /**
     * {@inheritdoc}
     */
    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setDefaults(array(
            'data_class' => BusVehiclesAmenities::class
        ));
    }

    /**
     * {@inheritdoc}
     */
    public function getBlockPrefix()
    {
        return 'appbundle_busvehiclesamenities';
    }


}

控制器。

/**
     * @Template
     */
    public function newAction(Request $request)
    {
        $bus = new BusVehicles();
        $busAmenities = new BusVehiclesAmenities();
        //   $this->getDoctrine()->getManager()->persist($busAmenities);
        $bus->setBusVehiclesAmenities($busAmenities);
        $form = $this->createForm(BusVehiclesType::class, $bus);
        $form->handleRequest($request);
        if ($form->isSubmitted() && $form->isValid()) {

            $em = $this->getDoctrine()->getManager();
            /*$form->get('busVehiclesAmenities')->getData()->map(
                function ($amenities) use ($em, $bus) {

                    $bus->setBusVehiclesAmenities($amenities);
                    $em->persist($amenities);
                }
            );*/
            $em->persist($bus);

            $em->flush();

            // Adding flash message to our user

            $this->addFlash('success', 'admin.bus.created');


            //  return $this->redirectToRoute('bus_add');

        }
        return [
            'form' => $form->createView(),
        ];
    }

【问题讨论】:

    标签: php symfony doctrine-orm symfony-forms symfony-3.1


    【解决方案1】:

    我遇到了与您类似的问题。我为解决这种情况所做的就是删除 JoinColumn。它实际上是多余的。这是关于 Symfony 的那些“神奇”事情之一,它可以让恕我直言烦人。只需确保您的 OneToMany 注释正确指向您的 ManyToOne。这是一个例子——这是在我的 User.php 实体中:

    /**
     * @ORM\OneToMany(targetEntity="AppBundle\Entity\UserStats", mappedBy="user")
     */
    private $userStats;
    

    这是在被加入的实体中(UserStats.php):

    /**
     * @ORM\ManyToOne(targetEntity="AppBundle\Entity\User",
     *     inversedBy="userStats")
     *
     */
    private $user;
    

    如您所见,没有 JoinColumn,因此一切运行良好。我希望这可以帮助你。 :)

    确保您使用我上面所说的正确路径,即

    * (targetEntity="AppBundle\Entity\User", inversedBy="userStats")
    

    【讨论】:

    • 感谢您的评论。我使用了你的建议,但我遇到了学说映射错误。将用新的错误更新我的帖子
    • 我想同样的事情也发生在我身上,最后没有使用JoinColumn。期待看到您的更新。
    • 好的——删除这个:@ORM\JoinColumn(name="amenities_id", referencedColumnName="id")。任何一个实体中都不需要有 JoinColumn。如果你看我的例子,我在任何一个中都没有,这是我最初指出的。我敢打赌这可以解决。
    • 我将它们全部从公共汽车设施中移除,但错误仍然存​​在。我在公共汽车实体中还剩下一些。我将删除所有这些并回发结果
    • 我认为您使用错误的格式来引用您的实体,即我的示例中的“AppBundle\Entity\User”。您所说的只是实体名称。我认为您没有完整的路径。
    【解决方案2】:

    从 Amenity Entity (Child) 中删除这部分代码:

    public function __construct()
    {
        $this->bus = new ArrayCollection();
    }
    

    如果表单定义正确,它应该可以解决您的问题。

    解释 - 此实体中的总线是 OneToMany 关系的拥有方。它总是一个,它不能是一个集合。

    【讨论】:

    • 所以你必须与我们分享你的表格:-)
    【解决方案3】:

    BusVehiclesAmenities-&gt;bus 是一个对象,而不是一个集合。 $this-&gt;bus = new ArrayCollection(); 行没有理由存在于您的子实体中。

    您想在一个对象(总线)中实现多对一,一个多(元素)又名ArrayCollection

    编辑

    在您的控制器中,您执行以下操作

    $bus->setBusVehiclesAmenities($busAmenities);
    

    这不是必需的。表单将自行处理集合。 魔法

    您的错误可能来自此调用,但这是因为您试图说arrayCollection = object,这是不可能的。

      public function setBusVehiclesAmenities(BusVehiclesAmenities $busVehiclesAmenities)
        {
            // ArrayCollection = Object
            $this->busVehiclesAmenities = $busVehiclesAmenities;
            return $this;
        }
    

    您可以尝试执行setBusVehiclesAmenities(ArrayCollection $busVehiclesAmenities)Collection,我不知道,或者删除setBusVehiclesAmenities 方法。 (我个人会删除该方法)

    您还应该检查您孩子中 bus 的 getter/setter,这次您的变量是单个对象,只需执行 getBus()setBus($bus),而不是添加和删除。

    希望对你有帮助

    【讨论】:

    • 感谢您的回答。我删除了代码,但我在发布表单时仍然有同样的错误
    • 感谢您的时间和精力。如果控制器中没有“setBusVehiclesAmenities”,我形成的公共汽车设施集合是空的。
    猜你喜欢
    • 2019-07-13
    • 2021-04-22
    • 1970-01-01
    • 1970-01-01
    • 2015-01-27
    • 1970-01-01
    • 2015-07-22
    • 2014-02-09
    • 1970-01-01
    相关资源
    最近更新 更多