Symfony2 / Doctrine2 OneToMany相关实体没有反面的ID

时间:2013-06-20 21:43:11

标签: symfony doctrine-orm

我有2个相关实体,Invoice& InvoiceRow,我有一个表格让人们创建新发票。

我还加载了一些测试数据,我加载它们以使用测试数据为数据库播种,无论我如何将实体持久化到数据库,InvoiceRow中的invoice_id总是null

在灯具中我试过坚持发票

InvoiceRow.php:     

namespace Settleup\InvoiceBundle\Entity;

use Doctrine\ORM\Mapping as ORM;

/**
 * @ORM\Entity
 */
Class InvoiceRow {
    /**
     * @ORM\Column(name="id", type="integer", nullable=false)
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="IDENTITY")
     */
    protected $id;

    /**
     * @ORM\Column(type="string", length=100)
     */
    protected $description;

    /**
     * The invoice row amount, stored in "bottle tops", ie £1.00 is 10000 bottle tops
     * 
     * @ORM\Column(type="integer")
     */
    protected $amount;

    /**
     * The invoice this row belongs to.
     *
     * @ORM\ManyToOne(targetEntity="Settleup\InvoiceBundle\Entity\Invoice", inversedBy="rows")
     * @var integer
     **/
    protected $invoice;

    public function setDescription($description) {
        $this->description = $description;
    }

    public function getDescription() {
        return $this->description;
    }

    public function setAmount($amount) {
        $this->amount = $amount * 10000;
    }

    public function getAmount() {
        return $this->amount / 10000;
    }


    /**
     * Returns the invoice this row is attached to.
     *
     * @return Settleup\InvoiceBundle\Entity\Invoice The invoice.
     */
    public function getInvoice() {
        return $this->invoice;
    }

    /**
     * Set the invoice this row belongs to.
     *
     * @param Settleup\InvoiceBundle\Entity\Invoice $newinvoice The invoice.
     */
    public function setInvoice($invoice) {
        $this->invoice = $invoice;

        return $this;
    }

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

Invoice.php

<?php

namespace Settleup\InvoiceBundle\Entity;

use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\ArrayCollection;

use Sylius\Bundle\AddressingBundle\Model\AddressInterface;

use Settleup\InvoiceBundle\Exception\MerchantUpdateException;

/**
 * @ORM\Entity
 */
Class Invoice {
    /**
     * @ORM\Column(name="id", type="integer", nullable=false)
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="IDENTITY")
     */
    protected $id;

    /**
     * @ORM\Column(type="string", length=100)
     */
    protected $reference;

    /**
     * @ORM\Column(type="datetime")
     */
    protected $issueDate;

    /**
     * @ORM\OneToMany(targetEntity="Settleup\InvoiceBundle\Entity\InvoiceRow", mappedBy="invoice", cascade="persist")
     */
    protected $rows;

    /**
     * @ORM\ManyToOne(targetEntity="Settleup\UserBundle\Entity\User")
     */
    protected $merchant;

    /**
     * @ORM\ManyToOne(targetEntity="Settleup\InvoiceBundle\Entity\InvoiceAddress", cascade={"persist"})
     */
    protected $invoiceAddress;

    /**
     * undocumented function
     *
     * @return void
     * @author 
     **/
    public function __construct()
    {
        $this->rows = new ArrayCollection();

        $this->issueDate = new \DateTime();
    }

    /**
     * undocumented function
     *
     * @return void
     * @author 
     **/
    public function getId()
    {
        return $this->id;
    }

    /**
     * Returns all the rows on this invoice.
     *
     * @return ArrayCollection
     * @author 
     **/
    public function getRows()
    {
        return $this->rows;
    }

    /**
     * Set the reference for this invoice.
     *
     * @return void
     * @author 
     **/
    public function setReference($reference)
    {
        $this->reference = $reference;
    }

    /**
     * Returnt he invoice reference.
     *
     * @return string
     * @author 
     **/
    public function getReference()
    {
        return $this->reference;
    }

    /**
     * Sets the date this invoice was issued.
     *
     * @param  \DateTime $issueDate The date the invoice was issued.
     * @return void
     * @author 
     **/
    public function setIssueDate(\DateTime $issueDate)
    {
        $this->issueDate = $issueDate;
    }

    /**
     * Return the date the invoice was raised.
     *
     * @return \DateTime
     * @author 
     **/
    public function getIssueDate()
    {
        return $this->issueDate;
    }

    /**
     * Sets the collections of rows that make up this invoice.
     *
     * @return void
     * @author 
     **/
    public function setRows(ArrayCollection $rows)
    {
        $this->rows = $rows;
    }

    /**
     * Return the merchant for this invoice.
     *
     * @return Settleup\UserBundle\Entity\User
     * @author 
     **/
    public function getMerchant()
    {
        return $this->merchant;
    }

    /**
     * Returns an instance of SyliusAddress, the address this invoice is for.
     *
     * @return Settleup\InvoiceBundle\Entity\InvoiceAddress
     * @author 
     **/
    public function getInvoiceAddress()
    {
        return $this->invoiceAddress;
    }

    /**
     * Sets the address for this invoice
     *
     * @param Settleup\InvoiceBundle\Entity\InvoiceAddress invoiceAddress The address this invoice is for.
     *
     * @return void
     * @author 
     **/
    public function setInvoiceAddress(AddressInterface $invoiceAddress)
    {
        $this->invoiceAddress = $invoiceAddress;
    }

    /**
     * Add rows
     *
     * @param \Settleup\InvoiceBundle\Entity\InvoiceRow $rows
     * @return Invoice
     */
    public function addRow(\Settleup\InvoiceBundle\Entity\InvoiceRow $rows)
    {
        $this->rows[] = $rows;

        return $this;
    }

    /**
     * Remove rows
     *
     * @param \Settleup\InvoiceBundle\Entity\InvoiceRow $rows
     */
    public function removeRow(\Settleup\InvoiceBundle\Entity\InvoiceRow $rows)
    {
        $this->rows->removeElement($rows);
    }

    /**
     * Set merchant
     *
     * @param \Settleup\UserBundle\Entity\User $merchant
     * @return Invoice
     */
    public function setMerchant(\Settleup\UserBundle\Entity\User $merchant = null)
    {
        if ($this->id == null) {
            $this->merchant = $merchant;
        } else {
            throw new MerchantUpdateException("Unable to update the merchant for this invoice, you can only assign a merchant when creating the invoice.");
        }

        return $this;
    }

    /**
     * @TODO Find out why this method is needed.
     *
     * @return void
     * @author 
     **/
    public function getAddresses()
    {
    }

    public function setAddresses() {}
}

我有一个用于填充两个表中的行的表单:

class InvoiceType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('reference')
            ->add('rows', 'collection', array(
                    'type' => 'invoice_row',
                    'allow_add' => true,
                    'by_reference' => false
                ))
            ->add('invoiceAddress', 'sylius_address');

            $builder->addEventListener(
                FormEvents::PRE_SET_DATA,
                function(FormEvent $event) {
                    $form = $event->getForm();

                    $form->add('merchant', 'hidden');
                }
            );
    }

    public function setDefaultOptions(OptionsResolverInterface $resolver)
    {
        $resolver->setDefaults(array(
            'data_class' => 'Settleup\InvoiceBundle\Entity\Invoice',
            'cascade_validation' => true
        ));
    }

    public function getName()
    {
        return 'settleup_invoicebundle_invoicetype';
    }
}

使用控制器上的操作保存该表单时:

public function createAction(Request $request)
{
    $entity  = new Invoice();

    $form = $this->createForm(new InvoiceType(), $entity);
    $form->bind($request);

    if ($form->isValid()) {
        $em = $this->getDoctrine()->getManager();

        $entity->setMerchant($this->getUser());

        $em->persist($entity);
        $em->flush();

        return $this->redirect($this->generateUrl('invoice_show', array('id' => $entity->getId())));
    } else {

    }

    return array(
        'entity' => $entity,
        'form'   => $form->createView(),
    );
}

除了InvoiceRow缺少invoice_id之外,两行都包含所有正确的数据。

1 个答案:

答案 0 :(得分:0)

有点晚了但可能对其他人有用

1)尝试持有拥有方(具有FK的那一方),即invoiceRow

2)我遇到了持久存在相关实体的问题,因为id字段没有遵循默认值。添加它使它工作:

 * @ORM\ManyToOne(targetEntity="Personas", fetch="EAGER", inversedBy="cuentasCorriente", 
 * cascade={"persist", "refresh"})
 * @ORM\JoinColumn(name="persona_id", referencedColumnName="ID", nullable=false)

referencedColumnName =“ID”参见“ID”!=“id” 当我将Doctrine添加到遗留系统时,别无选择。