我无法在symfony2中写入嵌入式表单的数据库

I'm handle embebed form with symfony2 but I have this error:

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.

I have two entities named EmpresaExterna.php and Transportista.php where I have a foreign key from transportista to exmpresaexterna, So I make a embebed form to insert into both tables but I can do this.

This is my code for 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;

Obviously included the getters and setters.

For 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;

My forms are, RegistroTransportistaType.php, and 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';
}
}

My controller is this:

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()));   
}

I find another post that explain similar but they used onetomany whit inversedBy into table.

Finally this is my form in 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 %}

Sorry for the big explanation. I hope you can help me. Thank you!

The problem is that you are persisting your parent entity (Transportista) without persisting your child entity (EmpresaExterna) first. As it has no id yet (that's a new / non-managed one), Doctrine can't map it.

Try this in your controller:

    $em->persist($transportista->getNombreEmpresa());
    $em->persist($transportista);
    $em->flush();

Change the following code:

/**
* @ORM\Id
* @ORM\ManyToOne(targetEntity="GestionResiduos\EmpresaExternaBundle\Entity\EmpresaExterna")
* @ORM\JoinColumn(name="nombreEmpresa_id", referencedColumnName="nombreEmpresa")
*/

protected $nombreEmpresa;

To this:

/**
* @ORM\Id
* @ORM\ManyToOne(targetEntity="GestionResiduos\EmpresaExternaBundle\Entity\EmpresaExterna", cascade={"persist"})
* @ORM\JoinColumn(name="nombreEmpresa_id", referencedColumnName="nombreEmpresa")
*/

protected $nombreEmpresa;

This will allow you to just persist the main entity and all related entities will be saved too.

$em->persist($transportista);

You may need to add further code into your addMethod for the main entity for the nombreEmpresa relationship.