Oscar
Oscar

Reputation: 2047

Doctrine Tell me "new Entity was found" when i set a relationship ManyToOne but is not

  1. I have a Project with Symfony
  2. Create a form for a ner entity.

    class EquipoType extends AbstractType{
    /**
     * {@inheritdoc}
     */
     public function buildForm(FormBuilderInterface $builder, array $options)
     {
        $equipo = new Equipo();
    
        $builder
        ->add('unidades', IntegerType::class)
        ->add('accionComercial', EntityType::class, array(
            'class' => 'AppBundle\Entity\IndicoGpt\adelantoequipos\AccionComercial',
            'em' => 'adeq',
            'choices' => $equipo->getAccionComercial(),
            'choice_label' => 'nombre',
            'placeholder' => 'Elija Accion Comercial'
        ))
        ->add('modelo', TextType::class)
        ->add('save', SubmitType::class, array(
                'label' => 'Guardar Equipo',
                'attr' => array(
                    'class' => "btn btn-info",
                    'style' => "margin-top: 7px; margin-left:40%;"
                ))
        );
    
        $builder->get('modelo')
            ->addModelTransformer(new CallbackTransformer(
                function ($modelo) {
                    return $modelo ? $modelo->getModDescModelo() :  $modelo;
                },
                function ($modelo) use ($options) {
                    return $modelo ? $options['em']->getRepository(ModModelo::class)->findOneBy(array(
                        'modDescModelo' => $modelo
                    )) : $modelo;
                }
            ));
     public function configureOptions(OptionsResolver $resolver)
     {
        $resolver->setDefaults(array(
            'data_class' => 'AppBundle\Entity\IndicoGpt\adelantoequipos\Equipo',
            'em' => "adeq"
        ));
     }
    
     /**
      * {@inheritdoc}
      */
     public function getBlockPrefix()
     {
        return 'appbundle_indicogpt_adelantoequipos_equipo';
     }
    }
    
  3. This Entity has a relatuionship. (Equipo has Modelo[oneToMany], Modelo has Many Equipos[oneToMany] )

        class Equipo
    {
        /**
     * @var \AppBundle\Entity\IndicoGpt\catalogo\ModModelo
     *
     * @ORM\ManyToOne(targetEntity="AppBundle\Entity\IndicoGpt\catalogo\ModModelo")
     * @ORM\JoinColumns({
     *   @ORM\JoinColumn(name="modelo_id", referencedColumnName="MOD_ID_MODELO")
     * })
     */
    private $modelo;
    
  4. The entity Modelo is full of rows (in db) with types of equip models. Ergo an Equipo only need to save an existing Id of a Modelo row.

The problem appears when i do $emAedq->flush() Here is my controller:

    public function crearEquipo(Request $request){

     $emAdeq = $this->getDoctrine()->getManager('adeq');
     $emCatalogo = $this->getDoctrine()->getManager('catalogo');

     $equipo = new Equipo();
     $form = $this->createForm(EquipoType::class, $equipo, array(
        'action' => "crearEquipo",
        'em' =>  $emCatalogo,
        'attr' => array(
            'class' => "form"
        )
     ));

     $form->handleRequest($request);

     if ($form->isSubmitted()) {

         $equipo = $form->getData();

         $emAdeq->persist($equipo);

         $emAdeq->flush();

         $this->addFlash('exito', $equipo->getId());

         return $this->redirectToRoute('portadaAdelantoEquipos');
     }
    ...
  1. When I go to save the new Equipo it tells me that it was found a new entity in the relationship and should be saved (reffering to Modelo associated), but that entity is not new, it is an existing Modelo that is now related to the Equipo. enter image description here

As shown in the image, I choose a Modelo of the existing ones through an autocomplete field.

Just before doin the $emAdeq->persist($equipo) of the entity, i can see in the debugger the object that I am going to save it appears well composed: enter image description here

The Error is the next:

A new entity was found through the relationship 'AppBundle\Entity\IndicoGpt\adelantoequipos\Equipo#modelo' that was not configured to cascade persist operations for entity: AppBundle\Entity\IndicoGpt\catalogo\ModModelo@0000000011088ca600000000661c7dca. To solve this issue: Either explicitly call EntityManager#persist() on this unknown entity or configure cascade persist this association in the mapping for example @ManyToOne(..,cascade={"persist"}). If you cannot find out which entity causes the problem implement 'AppBundle\Entity\IndicoGpt\catalogo\ModModelo#__toString()' to get a clue.

I dont understand why thinks that is a new entity and why give me this string refering to modelo:

Why this happends? How can i save the Equipo with his relationship? Without make a persist of the Modelo because i can not save the Modelo that allready exist!

I have seen other example here. But this does not work to me...

I run this command php bin/console doctrine:schema:validate and everything is right.

Upvotes: 2

Views: 934

Answers (2)

Oscar
Oscar

Reputation: 2047

The problem is that I was using two entityManager because the relationship is made in two different databases.

But I have not realized that the related entity has his database established, so I only need one EntityManager.

With one entityManager i can ask for one entity and the relations without other EntityManagers

By having two entityManagers I was asked to saved twice.

Solution:

Establish in the entity his DB: * @ ORM \ Table (name = "advanced equipment.") Where I have used $emCatalgo replace it with $emAdeq and eliminate the catalog because it is unusable.

Thanks to @Alessandro Minoccheri because his answer is also valid but that make my realize what im doing wrong with 2 EntittyManagers.

Upvotes: 1

Alessandro Minoccheri
Alessandro Minoccheri

Reputation: 35963

You can configure cascade persist into your entity or you can change this:

$emAdeq->persist($equipo);

to this:

$emAdeq->merge($equipo);

Upvotes: 2

Related Questions