我无法在 symfony2 中以嵌入式形式写入数据库
I can't write into database with embebed form in symfony2
我正在使用 symfony2 处理嵌入表单,但出现此错误:
Entity of type GestionResiduos\EmpresaExternaBundle\Entity\Transportista has identity through a foreign entity GestionResiduos\EmpresaExternaBundle\Entity\EmpresaExterna, however this entity has no identity itself. You have to call EntityManager#persist() on the related entity and make sure that an identifier was generated before trying to persist 'GestionResiduos\EmpresaExternaBundle\Entity\Transportista'. In case of Post Insert ID Generation (such as MySQL Auto-Increment or PostgreSQL SERIAL) this means you have to call EntityManager#flush() between both persist operations.
我有两个名为 EmpresaExterna.php 和 Transportista.php 的实体,其中我有一个从 transportista 到 exmpresaexterna 的外键,所以我制作了一个嵌入表单以插入到两个 table 中,但是我可以做到这一点。
这是我的 EmpresaExterna.php 代码:
<?php
namespace GestionResiduos\EmpresaExternaBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\ArrayCollection;
/**
*@ORM\Entity(repositoryClass="GestionResiduos\EmpresaExternaBundle\Entity\EmpresaExternaRepository") */
class EmpresaExterna
{
/**
* @ORM\Id
* @ORM\column(type="string", length=80)
*/
protected $nombreEmpresa;
/**
* @ORM\column(type="string", length=60)
*/
protected $comuna;
/**
* @ORM\column(type="string", length=60)
*/
protected $correo;
/**
* @ORM\column(type="string", length=20)
*/
protected $telefono;
/**
* @ORM\column(type="string", length=60)
*/
protected $ciudad;
/**
* @ORM\column(type="string", length=100)
*/
protected $direccion;
/**
* @ORM\column(type="string", length=20)
*/
protected $rut;
/**
* @ORM\column(type="string", length=20)
*/
protected $numeroSidrep;
显然包括了 getter 和 setter。
对于Transportista.php:
<?php
namespace GestionResiduos\EmpresaExternaBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* @ORM\Entity(repositoryClass="EmpresaExternaRepository")
*/
class Transportista
{
/**
* @ORM\Id
* @ORM\ManyToOne(targetEntity="GestionResiduos\EmpresaExternaBundle\Entity\EmpresaExterna")
* @ORM\JoinColumn(name="nombreEmpresa_id", referencedColumnName="nombreEmpresa")
*/
protected $nombreEmpresa;
我的表格是 RegistroTransportistaType.php,RegistroEmpresaExternaType:
<?php
// src/Gestionresiudos/EmpresaExternaBundle/Form/RegistroResiduoType.php
namespace Gestionresiduos\EmpresaExternaBundle\Form;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;
class RegistroTransportistaType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('nombreEmpresa', new RegistroEmpresaExternaType())
->add('registrar', 'submit')
;
}
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$resolver->setDefaults(array('data_class' => 'Gestionresiduos\EmpresaExternaBundle\Entity\Transportista'));
}
public function getName()
{
return 'gestionresiduos_empresaexternabundle_registrotransportistatype';
}
}
RegistroEmpresaExternaType:
namespace Gestionresiduos\EmpresaExternaBundle\Form;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;
class RegistroEmpresaExternaType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('nombreEmpresa')
->add('comuna')
->add('correo')
->add('telefono')
->add('ciudad')
->add('direccion')
->add('rut')
->add('numeroSidrep')
;
}
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$resolver->setDefaults(array('data_class' => 'Gestionresiduos\EmpresaExternaBundle\Entity\EmpresaExterna'));
}
public function getName()
{
return 'gestionresiduos_empreasexternabundle_registroempreasexternatype';
}
}
我的控制器是这样的:
public function nuevoTransportistaAction(Request $request)
{
$transportista = new Transportista();
$empresaExterna = new EmpresaExterna();
$formulario = $this->createForm(new RegistroTransportistaType(), $transportista);
$formulario->handleRequest($request);
if($formulario->isValid())
{
//guardar la info en la base de datos
//setear el nombre de la empresa
$em = $this->getDoctrine()->getManager();
// $transportista->getNombreEmpresa();
$em->persist($transportista);
$em->flush();
//return $this->redirect($this->generateUrl('inicio'));
}
return $this->render('EmpresaExternaBundle:Default:registroTransportista.html.twig', array('formulario' => $formulario->createView()));
}
我发现另一个 post 解释类似,但他们使用了 onetomany whit inversedBy into table。
最后这是我在 twig 中的表格:
{#src/Gestionresiduos/SolicitudIngresoBundle/Resources/views/Default/solicitaringreso.html.twig #}
{% extends '::frontend.html.twig' %}
{% block id 'usuario' %}
{% block title %}Registro de nuevo transportista{% endblock %}
{% block article %}
<h1>{{ block('title') }}</h1>
{{ form_start(formulario)}}
{{ form_errors(formulario)}}
<div>
{{ form_label(formulario.nombreEmpresa.nombreEmpresa, 'Ingrese el nombre de la empresa') }}
<span>{{ form_widget(formulario.nombreEmpresa.nombreEmpresa)}}</span><br>
</div>
<div>
{{ form_label(formulario.nombreEmpresa.comuna, 'Ingrese comuna') }}
<span>{{ form_widget(formulario.nombreEmpresa.comuna)}}</span>
</div>
<div>
{{ form_label(formulario.nombreEmpresa.correo, 'Ingrese dirección email') }}
<span>{{ form_widget(formulario.nombreEmpresa.correo)}}</span><br>
</div>
<div>
{{ form_label(formulario.nombreEmpresa.telefono, 'Telefono') }}
<span>{{ form_widget(formulario.nombreEmpresa.telefono)}}</span><br>
</div>
<div>
{{ form_label(formulario.nombreEmpresa.ciudad, 'Ingrese ciudad') }}
<span>{{ form_widget(formulario.nombreEmpresa.ciudad)}}</span><br>
</div>
<div>
{{ form_label(formulario.nombreEmpresa.direccion, 'Indique dirección')}}
<span>{{ form_widget(formulario.nombreEmpresa.direccion)}}</span><br>
</div>
<div>
{{ form_label(formulario.nombreEmpresa.rut, 'Ingrese el rut de la empresa') }}
<span>{{ form_widget(formulario.nombreEmpresa.rut)}}</span><br>
</div>
<div>
{{ form_label(formulario.nombreEmpresa.numeroSidrep, 'Ingrese el número SIDREP') }}
<span>{{ form_widget(formulario.nombreEmpresa.numeroSidrep)}}</span><br>
</div>
<div>
{{ form_widget(formulario.registrar) }}
</div>
{{ form_rest(formulario) }}
{{ form_end(formulario)}}
{% endblock %}
{% block aside %}{% endblock %}
抱歉,解释得太多了。我希望你能帮助我。谢谢!
问题是您在没有先保留子实体 (EmpresaExterna
) 的情况下保留父实体 (Transportista
)。由于它还没有 id
(这是一个新的/非托管的),Doctrine 无法映射它。
在你的控制器中试试这个:
$em->persist($transportista->getNombreEmpresa());
$em->persist($transportista);
$em->flush();
更改以下代码:
/**
* @ORM\Id
* @ORM\ManyToOne(targetEntity="GestionResiduos\EmpresaExternaBundle\Entity\EmpresaExterna")
* @ORM\JoinColumn(name="nombreEmpresa_id", referencedColumnName="nombreEmpresa")
*/
protected $nombreEmpresa;
为此:
/**
* @ORM\Id
* @ORM\ManyToOne(targetEntity="GestionResiduos\EmpresaExternaBundle\Entity\EmpresaExterna", cascade={"persist"})
* @ORM\JoinColumn(name="nombreEmpresa_id", referencedColumnName="nombreEmpresa")
*/
protected $nombreEmpresa;
这将允许您仅保留主要实体,所有相关实体也将被保存。
$em->persist($transportista);
您可能需要在 addMethod 中为 nombreEmpresa 关系的主要实体添加更多代码。
我正在使用 symfony2 处理嵌入表单,但出现此错误:
Entity of type GestionResiduos\EmpresaExternaBundle\Entity\Transportista has identity through a foreign entity GestionResiduos\EmpresaExternaBundle\Entity\EmpresaExterna, however this entity has no identity itself. You have to call EntityManager#persist() on the related entity and make sure that an identifier was generated before trying to persist 'GestionResiduos\EmpresaExternaBundle\Entity\Transportista'. In case of Post Insert ID Generation (such as MySQL Auto-Increment or PostgreSQL SERIAL) this means you have to call EntityManager#flush() between both persist operations.
我有两个名为 EmpresaExterna.php 和 Transportista.php 的实体,其中我有一个从 transportista 到 exmpresaexterna 的外键,所以我制作了一个嵌入表单以插入到两个 table 中,但是我可以做到这一点。
这是我的 EmpresaExterna.php 代码:
<?php
namespace GestionResiduos\EmpresaExternaBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\ArrayCollection;
/**
*@ORM\Entity(repositoryClass="GestionResiduos\EmpresaExternaBundle\Entity\EmpresaExternaRepository") */
class EmpresaExterna
{
/**
* @ORM\Id
* @ORM\column(type="string", length=80)
*/
protected $nombreEmpresa;
/**
* @ORM\column(type="string", length=60)
*/
protected $comuna;
/**
* @ORM\column(type="string", length=60)
*/
protected $correo;
/**
* @ORM\column(type="string", length=20)
*/
protected $telefono;
/**
* @ORM\column(type="string", length=60)
*/
protected $ciudad;
/**
* @ORM\column(type="string", length=100)
*/
protected $direccion;
/**
* @ORM\column(type="string", length=20)
*/
protected $rut;
/**
* @ORM\column(type="string", length=20)
*/
protected $numeroSidrep;
显然包括了 getter 和 setter。
对于Transportista.php:
<?php
namespace GestionResiduos\EmpresaExternaBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* @ORM\Entity(repositoryClass="EmpresaExternaRepository")
*/
class Transportista
{
/**
* @ORM\Id
* @ORM\ManyToOne(targetEntity="GestionResiduos\EmpresaExternaBundle\Entity\EmpresaExterna")
* @ORM\JoinColumn(name="nombreEmpresa_id", referencedColumnName="nombreEmpresa")
*/
protected $nombreEmpresa;
我的表格是 RegistroTransportistaType.php,RegistroEmpresaExternaType:
<?php
// src/Gestionresiudos/EmpresaExternaBundle/Form/RegistroResiduoType.php
namespace Gestionresiduos\EmpresaExternaBundle\Form;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;
class RegistroTransportistaType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('nombreEmpresa', new RegistroEmpresaExternaType())
->add('registrar', 'submit')
;
}
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$resolver->setDefaults(array('data_class' => 'Gestionresiduos\EmpresaExternaBundle\Entity\Transportista'));
}
public function getName()
{
return 'gestionresiduos_empresaexternabundle_registrotransportistatype';
}
}
RegistroEmpresaExternaType:
namespace Gestionresiduos\EmpresaExternaBundle\Form;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;
class RegistroEmpresaExternaType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('nombreEmpresa')
->add('comuna')
->add('correo')
->add('telefono')
->add('ciudad')
->add('direccion')
->add('rut')
->add('numeroSidrep')
;
}
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$resolver->setDefaults(array('data_class' => 'Gestionresiduos\EmpresaExternaBundle\Entity\EmpresaExterna'));
}
public function getName()
{
return 'gestionresiduos_empreasexternabundle_registroempreasexternatype';
}
}
我的控制器是这样的:
public function nuevoTransportistaAction(Request $request)
{
$transportista = new Transportista();
$empresaExterna = new EmpresaExterna();
$formulario = $this->createForm(new RegistroTransportistaType(), $transportista);
$formulario->handleRequest($request);
if($formulario->isValid())
{
//guardar la info en la base de datos
//setear el nombre de la empresa
$em = $this->getDoctrine()->getManager();
// $transportista->getNombreEmpresa();
$em->persist($transportista);
$em->flush();
//return $this->redirect($this->generateUrl('inicio'));
}
return $this->render('EmpresaExternaBundle:Default:registroTransportista.html.twig', array('formulario' => $formulario->createView()));
}
我发现另一个 post 解释类似,但他们使用了 onetomany whit inversedBy into table。
最后这是我在 twig 中的表格:
{#src/Gestionresiduos/SolicitudIngresoBundle/Resources/views/Default/solicitaringreso.html.twig #}
{% extends '::frontend.html.twig' %}
{% block id 'usuario' %}
{% block title %}Registro de nuevo transportista{% endblock %}
{% block article %}
<h1>{{ block('title') }}</h1>
{{ form_start(formulario)}}
{{ form_errors(formulario)}}
<div>
{{ form_label(formulario.nombreEmpresa.nombreEmpresa, 'Ingrese el nombre de la empresa') }}
<span>{{ form_widget(formulario.nombreEmpresa.nombreEmpresa)}}</span><br>
</div>
<div>
{{ form_label(formulario.nombreEmpresa.comuna, 'Ingrese comuna') }}
<span>{{ form_widget(formulario.nombreEmpresa.comuna)}}</span>
</div>
<div>
{{ form_label(formulario.nombreEmpresa.correo, 'Ingrese dirección email') }}
<span>{{ form_widget(formulario.nombreEmpresa.correo)}}</span><br>
</div>
<div>
{{ form_label(formulario.nombreEmpresa.telefono, 'Telefono') }}
<span>{{ form_widget(formulario.nombreEmpresa.telefono)}}</span><br>
</div>
<div>
{{ form_label(formulario.nombreEmpresa.ciudad, 'Ingrese ciudad') }}
<span>{{ form_widget(formulario.nombreEmpresa.ciudad)}}</span><br>
</div>
<div>
{{ form_label(formulario.nombreEmpresa.direccion, 'Indique dirección')}}
<span>{{ form_widget(formulario.nombreEmpresa.direccion)}}</span><br>
</div>
<div>
{{ form_label(formulario.nombreEmpresa.rut, 'Ingrese el rut de la empresa') }}
<span>{{ form_widget(formulario.nombreEmpresa.rut)}}</span><br>
</div>
<div>
{{ form_label(formulario.nombreEmpresa.numeroSidrep, 'Ingrese el número SIDREP') }}
<span>{{ form_widget(formulario.nombreEmpresa.numeroSidrep)}}</span><br>
</div>
<div>
{{ form_widget(formulario.registrar) }}
</div>
{{ form_rest(formulario) }}
{{ form_end(formulario)}}
{% endblock %}
{% block aside %}{% endblock %}
抱歉,解释得太多了。我希望你能帮助我。谢谢!
问题是您在没有先保留子实体 (EmpresaExterna
) 的情况下保留父实体 (Transportista
)。由于它还没有 id
(这是一个新的/非托管的),Doctrine 无法映射它。
在你的控制器中试试这个:
$em->persist($transportista->getNombreEmpresa());
$em->persist($transportista);
$em->flush();
更改以下代码:
/**
* @ORM\Id
* @ORM\ManyToOne(targetEntity="GestionResiduos\EmpresaExternaBundle\Entity\EmpresaExterna")
* @ORM\JoinColumn(name="nombreEmpresa_id", referencedColumnName="nombreEmpresa")
*/
protected $nombreEmpresa;
为此:
/**
* @ORM\Id
* @ORM\ManyToOne(targetEntity="GestionResiduos\EmpresaExternaBundle\Entity\EmpresaExterna", cascade={"persist"})
* @ORM\JoinColumn(name="nombreEmpresa_id", referencedColumnName="nombreEmpresa")
*/
protected $nombreEmpresa;
这将允许您仅保留主要实体,所有相关实体也将被保存。
$em->persist($transportista);
您可能需要在 addMethod 中为 nombreEmpresa 关系的主要实体添加更多代码。