Doctrine - 不保存外键(值为空)

Doctrine - not saving foreign key (value is null)

我有两个具有 OneToMany/ManyToOne 关系的实体(trip 和 tripAddOn)。一个行程可以有多个tripAddOn,一个tripAddOn只能属于一个行程。

在我的控制器 class 中,我尝试保留行程,它成功地保留了行程和 tripAddOn,但是在 tripAddOn table 上,关联丢失了(trip_id 为空)。

class Trip {

   /**
   * @ORM\Id()
   * @ORM\GeneratedValue(strategy="AUTO")
   *
   * @var int
   */
   protected $id;

   /**
   * @ORM\OneToMany(
   *     targetEntity="AppBundle\Entity\TripAddOn",
   *     mappedBy="trip",
   *     cascade={"persist"}
   * )
   *
   * @var ArrayCollection
   */
   protected $tripAddOns;

   /**
   * @return ArrayCollection
   */
   public function getTripAddOns()
   {
     return $this->tripAddOns;
   }

   /**
   * @param ArrayCollection $tripAddOns
   * @return self
   */
   public function setTripAddOns(ArrayCollection $tripAddOns)
   {
      $this->tripAddOns = $tripAddOns;

      return $this;
   }

   /**
   * @param TripAddOn $tripAddOn
   * @return self
   */
   public function addTripAddOn(TripAddOn $tripAddOn)
   {
       $tripAddOn->setTrip($this);
       $this->tripAddOns->add($tripAddOn);
       return $this;
   }
 }

TripAddOn.php

class TripAddOn
{
/**
 * @ORM\Id
 * @ORM\Column(type="integer", options={"unsigned"=true})
 * @ORM\GeneratedValue(strategy="AUTO")
 *
 * @var int
 */
protected $id;

/**
 * @ORM\ManyToOne(
 *     targetEntity="AppBundle\Entity\Trip",
 *     inversedBy="trip_add_ons",
 *     cascade={"persist"}
 * )
 * @ORM\JoinColumn(name="trip_id", referencedColumnName="id")
 *
 * @var Trip
 */
protected $trip;
/**
 * Get Trip
 *
 * @return Trip
 */
public function getTrip()
{
    return $this->trip;
}

/**
 * @param Trip $trip
 * @return self
 */
public function setTrip(Trip $trip)
{
    $this->trip = $trip;
    return $this;
}

public function addTrip(Trip $trip)
{
    $this->trip = $trip;
    return $this;
}

控制器:

 $entityManager = $this->getDoctrine()->getManager();
 $entityManager->persist($trip);
 $entityManager->flush();

同样,tripAddOn 已保存,但 trip_id 为空。就好像 TripAddOn.php 上的 "setTrip" 没有被识别。

更新*:更改了 Trip.php 中的 "setTripAddOns" 方法。我注意到当我在 "setTripAddOns" 和 "addTripAddOn" 中都设置断点时,两者都没有被击中。我通过使用 CollectionType for TripAddOns 的表单创建这些对象。

TripType.php

class TripType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('tripAddOns', CollectionType::class, [
                'entry_type' => TripAddOnType::class,
                'entry_options' => [
                    'data_class' => TripAddOn::class,
                ],
                'allow_add' => true,
                'allow_delete' => true,
            ])
    }
}

TripAddOnType.php

class TripAddOnType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('name', TextType::class)
            ->add('price', TextType::class)
        ;
    }

    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setDefaults([
            'data_class' => TripAddOn::class
        ]);
    }
}

在 Trip class 中你需要在构造函数中初始化 $tripAddOns:

public __construct() {
    this->tripAddOns = new ArrayCollection();
}

试试这些:

bin/console doctrine:cache:clear-metadata

bin/console doctrine:cache:clear-query

应该够了

/**
* @param TripAddOn $tripAddOn
* @return self
*/
public function addTripAddOn(TripAddOn $tripAddOn)
{
   $this->tripAddOns[] = $tripAddOn;

   return $this;
}

确保$trip->addTripAddon($tripAddonObject)在你的控制器中使用类似之前的东西。

我在这里发现了问题。 "setTripAddOns" 或 "addTripAddOn" 都没有被调用,所以 Trip 和 TripAddOn 之间没有关联。

Symfony 集合表单通过使用

连接两个实体
$trip->getTripAddOns->add($tripAddOn)

避免使用"add"和"set"方法。要更改此默认行为,您需要在集合表单字段上将名为 'by_reference' 的选项设置为 false。