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。
我有两个具有 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。