我有这些实体有一对多的关系:
freightOrder has many shipments
shipment has many shipmentLines
freightOrder实体如下所示:
<?php
namespace Fraktportalen\Bundle\ShipmentBundle\Entity;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\ORM\Mapping as ORM;
use JMS\Serializer\Annotation\ExclusionPolicy;
use JMS\Serializer\Annotation\Expose;
/**
* @ORM\Entity
* @ORM\HasLifecycleCallbacks
* @ExclusionPolicy("all")
*/
class FreightOrder
{
/**
* @Expose
*
* @ORM\Id
* @ORM\Column(type="integer")
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* @Expose
*
* @ORM\OneToMany(
* targetEntity="Fraktportalen\Bundle\ShipmentBundle\Entity\Shipment",
* mappedBy="freightOrder",
* cascade={"persist","remove"}
* )
*/
private $shipments;
/**
* @Expose
*
* @ORM\ManyToOne(targetEntity="Fraktportalen\Bundle\AccountBundle\Entity\Account")
* @ORM\JoinColumn(name="freighter_id", referencedColumnName="id")
*/
private $freighter;
/**
* Order constructor.
*/
public function __construct()
{
$this->shipments = new ArrayCollection();
}
/**
* @return mixed
*/
public function getId()
{
return $this->id;
}
/**
* @return mixed
*/
public function getShipments()
{
return $this->shipments;
}
/**
* @param mixed $shipment
*/
public function addShipment(Shipment $shipment)
{
$shipment->setFreightOrder($this);
$this->shipments->add($shipment);
}
public function removeShipment(Shipment $shipment)
{
$this->shipments->removeElement($shipment);
}
/**
* @return mixed
*/
public function getFreighter()
{
return $this->freighter;
}
/**
* @param mixed $freighter
*/
public function setFreighter($freighter)
{
$this->freighter = $freighter;
}
}
装运实体:
<?php
namespace Fraktportalen\Bundle\ShipmentBundle\Entity;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\ORM\Mapping as ORM;
use Fraktportalen\Bundle\AccountBundle\Entity\Account;
use Fraktportalen\Bundle\AddressBundle\Entity\Address;
use JMS\Serializer\Annotation\ExclusionPolicy;
use JMS\Serializer\Annotation\Expose;
/**
* @ORM\Entity
* @ORM\HasLifecycleCallbacks
* @ExclusionPolicy("all")
*/
class Shipment
{
/**
* @Expose
*
* @ORM\Id
* @ORM\Column(type="integer")
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* @Expose
*
* @ORM\Column(type="datetime", nullable=true)
*/
private $pickup;
/**
* @Expose
*
* @ORM\Column(type="datetime", nullable=true)
*/
private $delivery;
/**
* @Expose
*
* @ORM\OneToMany(
* targetEntity="Fraktportalen\Bundle\ShipmentBundle\Entity\ShipmentLine",
* mappedBy="shipment",
* fetch="EAGER",
* cascade={"persist"}
* )
*/
private $shipmentLines;
/**
* @Expose
*
* @ORM\ManyToOne(targetEntity="Fraktportalen\Bundle\ShipmentBundle\Entity\FreightOrder", inversedBy="shipments")
* @ORM\JoinColumn(name="freight_order_id", referencedColumnName="id", nullable=false)
*/
private $freightOrder;
/**
* @Expose
*
* @ORM\ManyToOne(targetEntity="Fraktportalen\Bundle\AccountBundle\Entity\Account")
* @ORM\JoinColumn(name="sender_id", referencedColumnName="id")
*/
private $sender;
/**
* @Expose
*
* @ORM\ManyToOne(targetEntity="Fraktportalen\Bundle\AccountBundle\Entity\Account")
* @ORM\JoinColumn(name="receiver_id", referencedColumnName="id")
*/
private $receiver;
/**
* Shipment constructor.
*/
public function __construct()
{
$this->shipmentLines = new ArrayCollection();
}
/**
* @return mixed
*/
public function getId()
{
return $this->id;
}
/**
* @return mixed
*/
public function getFreightOrder() {
return $this->freightOrder;
}
/**
* @param mixed $freightOrder
*
* @return Shipment
*/
public function setFreightOrder($freightOrder) {
$this->freightOrder = $freightOrder;
$freightOrder->addShipment($this);
return $this;
}
/**
* @return mixed
*/
public function getPickup()
{
return $this->pickup;
}
/**
* @param mixed $pickup
*/
public function setPickup(\DateTime $pickup = null)
{
$this->pickup = $pickup;
}
/**
* @return mixed
*/
public function getDelivery()
{
return $this->delivery;
}
/**
* @param mixed $delivery
*/
public function setDelivery(\DateTime $delivery = null)
{
$this->delivery = $delivery;
}
/**
* @return mixed
*/
public function getShipmentLines()
{
return $this->shipmentLines;
}
/**
* @param mixed $shipmentLine
*/
public function addShipmentLine(ShipmentLine $shipmentLine)
{
$shipmentLine->setShipment($this);
$this->shipmentLines->add($shipmentLine);
}
public function removeShipmentLine(ShipmentLine $shipmentLine)
{
$this->shipmentLines->removeElement($shipmentLine);
}
/**
* @return mixed
*/
public function getSender()
{
return $this->sender;
}
/**
* @param mixed $sender
*/
public function setSender(Account $sender)
{
$this->sender = $sender;
}
/**
* @return mixed
*/
public function getReceiver()
{
return $this->receiver;
}
/**
* @param mixed $receiver
*/
public function setReceiver(Account $receiver)
{
$this->receiver = $receiver;
}
}
FreightOrderType next:
<?php
namespace Fraktportalen\Bundle\ShipmentBundle\Form;
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\CollectionType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
class FreightOrderType extends AbstractType
{
/**
* {@inheritdoc}
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('freighter', EntityType::class, array(
'class' => 'AccountBundle:Account',
))
->add('shipments', CollectionType::class, array(
'entry_type' => ShipmentType::class,
'allow_add' => true
))
;
}
/**
* {@inheritdoc}
*/
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'Fraktportalen\Bundle\ShipmentBundle\Entity\FreightOrder',
'csrf_protection' => false
));
}
/**
* {@inheritdoc}
*/
public function getBlockPrefix()
{
return 'freightOrder';
}
}
从Ember应用程序保存货运单时,会发送此json:
{
"freightOrder": {
"freighter": "3",
"shipments": [{
"pickup": "2017-03-22 12:32:00",
"delivery": "2017-03-23 12:32:00",
"sender": "1",
"receiver": "2",
"shipment_lines": [{
"package_weight": 45,
"package_length": 240,
"package_width": 120,
"package_height": 240,
"package_type": "3"
}]
}]
}
}
除了不保存货件上的cargoOrder外,一切都按预期工作。即使我将它添加到freightOrder实体addShipment
函数:
/**
* @param mixed $shipment
*/
public function addShipment(Shipment $shipment)
{
$shipment->setFreightOrder($this);
$this->shipments->add($shipment);
}
正如您在货运实体中看到的那样,我甚至尝试将货件添加到货运单。但没有任何作用。
虽然发货线路也会被添加到货件中,这也是一对多的关系。
我是否必须向freightOrderType添加表单事件侦听器并手动将freightOrder添加到所有货件?我的印象是,在向FreightOrder添加所述货件时将货运单添加到货件中会解决它。至少这是我在搜索SO时发现的。
谢谢你的时间, 托米
答案 0 :(得分:3)
我感觉到你的痛苦,我经常与这个问题作斗争。
这听起来像是没有被召集的人。您有时可以通过将by_reference声明为false来解决此问题。
试试这个..
$builder
->add('freighter', EntityType::class, array(
'class' => 'AccountBundle:Account',
))
->add('shipments', CollectionType::class, array(
'entry_type' => ShipmentType::class,
'allow_add' => true,
'by_reference' => false,
))
;
阅读文档:
同样,如果您正在使用CollectionType字段,其中您的基础集合数据是一个对象(如与Doctrine的ArrayCollection一样),那么如果您需要加法器和移除器,则必须将by_reference设置为false(例如,要调用的addAuthor()和removeAuthor())。
就我个人而言,我仍然认为by_reference
对于他们曾经犯过的错误是一种骇人听闻的修复方法。我想我们永远不会知道..