Ошибка Symfony 2 в нескольких вложенных формах

0

У меня есть странная ошибка для множественной встроенной формы с symfony2.

Вот моя структура:

Лицензиат <- OneToMany → Регистрация <- OneToMany → Оплата

Лицензиат:

/**
 * @ORM\OneToMany(targetEntity="cM\ManagementBundle\Entity\Registration", mappedBy="licensee", cascade={"persist" })
 */
private $registrations;

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

public function addRegistration(\cM\ManagementBundle\Entity\Registration $registration)
{
    $this->registrations[] = $registration;
    $registration->setLicensee($this);

    return $this;
}

public function removeRegistration(\cM\ManagementBundle\Entity\Registration $registration)
{
    $this->registrations->removeElement($registration);
}

public function setRegistrations(ArrayCollection $registrations)
{
    foreach ($registrations as $registration) {
        $registration->addLicensee($this);
    }

    $this->registrations = $registrations;
}

public function getRegistrations() {
    return $this->registrations;
}

Регистрация:

/**
 * @ORM\ManyToOne(targetEntity="cM\ManagementBundle\Entity\Licensee", inversedBy="registrations")
 * @ORM\JoinColumn(nullable=false)
 */
private $licensee;

/**
 * @ORM\OneToMany(targetEntity="cM\ManagementBundle\Entity\Payment", mappedBy="registration", cascade={"ALL"}, orphanRemoval=true)
 * @ORM\JoinColumn(nullable=false)
 */
private $payments;

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

/**
 * Set licensee
 *
 * @param \cM\ManagementBundle\Entity\Licensee $licensee
 * @return Registration
 */
public function setLicensee(\cM\ManagementBundle\Entity\Licensee $licensee)
{
    $this->licensee = $licensee;

    return $this;
}

/**
 * Get licensee
 *
 * @return \cM\ManagementBundle\Entity\Licensee 
 */
public function getLicensee()
{
    return $this->licensee;
}

/**
 * Add payments
 *
 * @param \cM\ManagementBundle\Entity\Payment $payment
 * @return Registration
 */
public function addPayment(\cM\ManagementBundle\Entity\Payment $payment)
{
    $payment->setRegistration($this);
    $this->payments[] = $payment;

    return $this;
}

/**
 * Remove payments
 *
 * @param \cM\ManagementBundle\Entity\Payment $payment
 */
public function removePayment(\cM\ManagementBundle\Entity\Payment $payment)
{
    $this->payments->removeElement($payment);
}

/**
 * Get payments
 *
 * @return \Doctrine\Common\Collections\Collection 
 */
public function getPayments()
{
    return $this->payments;
}

Оплата:

/**
 * @ORM\ManyToOne(targetEntity="cM\ManagementBundle\Entity\Registration", inversedBy="payments")
 * @ORM\JoinColumn(nullable=false, onDelete="CASCADE")
 */
private $registration;

/**
 * Set registration
 *
 * @param \cM\ManagementBundle\Entity\Registration $registration
 * @return Payment
 */
public function setRegistration(\cM\ManagementBundle\Entity\Registration $registration)
{
    $this->registration = $registration;

    return $this;
}

/**
 * Get registration
 *
 * @return \cM\ManagementBundle\Entity\Registration 
 */
public function getRegistration()
{
    return $this->registration;
}

Тип лицензии:

$builder
        ->add('registrations', 'collection', array(
            'type'         => new RegistrationType(),
            'allow_add'    => true,
            'by_reference' => false,
        ))

Тип регистрации:

$builder
        ->add('payments', 'collection', array(
            'type'         => new PaymentType(),
            'allow_add'    => true,
            'allow_delete' => true,
            'by_reference' => false,
            'required'     => false,
        ))

Тип платежа:

$builder
        ->add('amount', 'text')

Мой главный контроллер: LicenseeController

$form = $this->createForm('cm_managementbundle_licensee', $licensee);
$form->handleRequest($this->getRequest());

if ($this->getRequest()->getMethod() === 'POST') {
    if ($form->isValid()) {
        $em = $this->getDoctrine()->getManager();
        $em->persist($licensee);

        $em->flush();

        return $this->redirect($this->generateUrl('homepage'));
    }
}

В форме Лицензиата регистрация является обязательной, но платежи являются дополнительными.

  • Когда я создаю нового лицензиата с регистрационной информацией и без оплаты: его нормально и информация хорошо сохраняются в базе данных
  • когда я редактирую лицензию и добавляю некоторые платежи: в порядке
  • когда я создаю нового лицензиата с регистрационной информацией и с одной или несколькими платежами, есть ошибка доктрины, в которой регистрация не может быть нулевой:

    Исключение произошло при выполнении "INSERT INTO Registration (registrationDate, registrationNumber,...) VALUES (?,?,...) 'с параметрами [null, null,...]:

    SQLSTATE [23000]: Нарушение ограничения целостности: 1048 Столбец 'registrationDate' не может быть нулевым

Когда я смотрю на профилировщик symfony, я вижу, что эта доктрина запускает 2 запроса для таблицы регистрации:

- "START TRANSACTION"
- INSERT INTO Licensee (lastname, firstname, ...) VALUES (?, ?, ...)
Parameters: { 1: Simpson, 2: Homer, ... }
- INSERT INTO Registration (registrationDate, registrationNumber, ...) VALUES (?, ?, ...)
Parameters: { 1: '2015-01-29 00:00:00', 2: '1234', ... }
- INSERT INTO Registration (registrationDate, registrationNumber, ...) VALUES (?, ?, ...)
Parameters: { 1: null, 2: null, ... }

Поймите, почему существует второй запрос на регистрацию со всеми параметрами, равными нулю, в то время как первое верно?

Что мне не хватает?

Спасибо за любого короля за помощь.

Теги:
forms
doctrine2

1 ответ

0
Лучший ответ

Хорошо, это удалось решить.

мне нужно изменить имя прототипа коллекции платежей

->add('payments', 'collection', array(
    'type' => new PaymentType(),
    'allow_add' => true,
    'prototype_name' => 'payments_name'
))

поэтому, когда я динамически меняю имя с помощью javascript при добавлении нового платежа, я не изменяю родительское имя (Регистрация) в процессе (по умолчанию все коллекции прототипов имеют одно и то же имя (имя)

Благодаря Waiting for Dev... для подсказок

Ещё вопросы

Сообщество Overcoder
Наверх
Меню