I can't remove related objects with entity Manager flush outside a loop

I'm trying to remove Libreta's related objects from Caja objects but removing isnt working when I use flush() outside the foreach code when in other code or examples I can do the same thing with flush outside the code. Why?

This is the part of the code that work

Working example

$formulario->handleRequest($peticion);
        if ($formulario->isValid()) {

            if($formulario->get('regresar')->isClicked()){
                return $this->redirect($this->generateUrl('super_admin_main_caja'));
            }

            if($formulario->get('guardar')->isClicked()){
                $caja = $formulario->getData();
                $em = $this->getDoctrine()->getManager();
                $em->persist($caja);
                $em->flush();

                return $this->redirect($this->generateUrl('super_admin_update_caja', array('cajaId' => $caja->getId())));
            }

            if($formulario->get('deshabilitar_caja')->isClicked()){
                $caja = $formulario->getData();
                $em = $this->getDoctrine()->getManager();

                foreach ($caja->getLibretas() as $libreta) {
                    $libreta->setCaja(NULL);
                    $em->remove($libreta);  
                    $em->flush();
                }

                $caja->setEstado('DESHABILITADO');
                $em->persist($caja);
                $em->flush();

                return $this->redirect($this->generateUrl('super_admin_main_caja'));

            }

But when I try same code but with this modification, I cant remove the related objects and I dont get any error

foreach ($caja->getLibretas() as $libreta) {
                        $libreta->setCaja(NULL);
                        $em->remove($libreta);
                    }

                    $caja->setEstado('DESHABILITADO');
                    $em->persist($caja);
                    $em->flush();

Caja.php

    <?php

namespace PD\AppBundle\Entity;

use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;
use APY\DataGridBundle\Grid\Mapping as GRID;

/**
 *
 * @ORM\Entity
 * @ORM\Table(name="caja") 
 * 
 */
class Caja
{
    /**
     * 
     * @ORM\Id 
     * @ORM\Column(type="integer") 
     * @ORM\GeneratedValue
     */
    protected $id;

    /** 
     * @ORM\Column(type="string", length=100)
     * @GRID\Column(title="Número carton")
    */
    protected $numero_carton;

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

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

    /** 
    * @ORM\Column(type="string", length=100) 
    * @GRID\Column(title="Libretas omitidas")
    */
    protected $omite_libreta;

    /** 
     * @ORM\Column(type="string", length=100) 
     * @GRID\Column(title="Total libretas")
     */
    protected $total_libretas;

    /** @ORM\ManyToOne(targetEntity="PD\AppBundle\Entity\Juego") 
     *  @ORM\JoinColumn(name="juego_id", referencedColumnName="id")
     * */
    protected $juego;

    /** @ORM\ManyToOne(targetEntity="PD\AppBundle\Entity\Usuario") **/
    protected $usuario;

    /**
     * @ORM\Column(type="datetime", nullable=true)
     * @GRID\Column(title="Fecha creación")
     */
    protected $fecha_creacion;

    /**
     * @var boolean
     *
     * @ORM\Column(name="estado", type="string", length=50)
     * @GRID\Column(title="Estado")
     */
    protected $estado;
    /* 
     * 1 = CREADO
     * 2 = ASIGNADO_A_SUPERVISOR
     * 3 = FINALIZADO_CON_EXITO
     * 4 = FINALIZADO_CON_OBSERVACIONES
     * 5 = DESHABILITADO
     * 
     */

    /**
     * @ORM\OneToMany(targetEntity="PD\AppBundle\Entity\Libreta", mappedBy="caja", cascade={"remove", "persist"})
     */
    protected $libretas;


    public function __construct()
    {
        $this->fecha_creacion = new \DateTime();
        $this->libretas = new \Doctrine\Common\Collections\ArrayCollection();
    }

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

    /**
     * Set numero_carton
     *
     * @param string $numeroCarton
     * @return Caja
     */
    public function setNumeroCarton($numeroCarton)
    {
        $this->numero_carton = $numeroCarton;

        return $this;
    }

    /**
     * Get numero_carton
     *
     * @return string 
     */
    public function getNumeroCarton()
    {
        return $this->numero_carton;
    }

    /**
     * Set contiene_libreta_limite_inferior
     *
     * @param string $contieneLibretaLimiteInferior
     * @return Caja
     */
    public function setContieneLibretaLimiteInferior($contieneLibretaLimiteInferior)
    {
        $this->contiene_libreta_limite_inferior = $contieneLibretaLimiteInferior;

        return $this;
    }

    /**
     * Get contiene_libreta_limite_inferior
     *
     * @return string 
     */
    public function getContieneLibretaLimiteInferior()
    {
        return $this->contiene_libreta_limite_inferior;
    }

    /**
     * Set contiene_libreta_limite_superior
     *
     * @param string $contieneLibretaLimiteSuperior
     * @return Caja
     */
    public function setContieneLibretaLimiteSuperior($contieneLibretaLimiteSuperior)
    {
        $this->contiene_libreta_limite_superior = $contieneLibretaLimiteSuperior;

        return $this;
    }

    /**
     * Get contiene_libreta_limite_superior
     *
     * @return string 
     */
    public function getContieneLibretaLimiteSuperior()
    {
        return $this->contiene_libreta_limite_superior;
    }

    /**
     * Set omite_libreta
     *
     * @param string $omiteLibreta
     * @return Caja
     */
    public function setOmiteLibreta($omiteLibreta)
    {
        $this->omite_libreta = $omiteLibreta;

        return $this;
    }

    /**
     * Get omite_libreta
     *
     * @return string 
     */
    public function getOmiteLibreta()
    {
        return $this->omite_libreta;
    }

    /**
     * Set total_libretas
     *
     * @param string $totalLibretas
     * @return Caja
     */
    public function setTotalLibretas($totalLibretas)
    {
        $this->total_libretas = $totalLibretas;

        return $this;
    }

    /**
     * Get total_libretas
     *
     * @return string 
     */
    public function getTotalLibretas()
    {
        return $this->total_libretas;
    }

    /**
     * Set juego
     *
     * @param \PD\AppBundle\Entity\Juego $juego
     * @return Caja
     */
    public function setJuego(\PD\AppBundle\Entity\Juego $juego)
    {
        $this->juego = $juego;
    }

    /**
     * Get juego
     *
     * @return \PD\AppBundle\Entity\Juego 
     */
    public function getJuego()
    {
        return $this->juego;
    }

    public function __toString()
    {
        return $this->getNumeroCarton();
    }

    /**
     * Set usuario
     *
     * @param \PD\AppBundle\Entity\Usuario $usuario
     * @return Caja
     */
    public function setUsuario(\PD\AppBundle\Entity\Usuario $usuario)
    {
        $this->usuario = $usuario;

        return $this;
    }

    /**
     * Get usuario
     *
     * @return \PD\AppBundle\Entity\Usuario 
     */
    public function getUsuario()
    {
        return $this->usuario;
    }

    /**
     * Set fecha_creacion
     *
     * @param \DateTime $fechaCreacion
     * @return Caja
     */
    public function setFechaCreacion($fechaCreacion)
    {
        $this->fecha_creacion = $fechaCreacion;

        return $this;
    }

    /**
     * Get fecha_creacion
     *
     * @return \DateTime 
     */
    public function getFechaCreacion()
    {
        return $this->fecha_creacion;
    }

    /**
     * Set estado
     *
     * @param string $estado
     * @return Caja
     */
    public function setEstado($estado)
    {
        $this->estado = $estado;

        return $this;
    }

    /**
     * Get estado
     *
     * @return string 
     */
    public function getEstado()
    {
        return $this->estado;
    }

    /**
     * Add libretas
     *
     * @param \PD\AppBundle\Entity\Libreta $libretas
     * @return Caja
     */
    public function addLibreta(\PD\AppBundle\Entity\Libreta $libretas)
    {
        //$this->libretas[] = $libretas;
        //return $this;

        $libretas->setCaja($this);
        $this->libretas->add($libretas);
        return $this;
    }

    /**
     * Remove libretas
     *
     * @param \PD\AppBundle\Entity\Libreta $libretas
     */
    public function removeLibreta(\PD\AppBundle\Entity\Libreta $libretas)
    {
        $this->libretas->removeElement($libretas);
    }

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

Libreta.php

    <?php

namespace PD\AppBundle\Entity;

use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;
use APY\DataGridBundle\Grid\Mapping as GRID;

/**
 * Libreta
 *
 * @ORM\Table()
 * @ORM\Entity
 */
class Libreta
{
    /**
     * @var integer
     *
     * @ORM\Column(name="id", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $id;

    /** 
      * @ORM\ManyToOne(targetEntity="PD\AppBundle\Entity\Caja", inversedBy="libretas") 
      * @ORM\JoinColumn(name="caja_id", referencedColumnName="id", nullable=false)
      * @Assert\Type(type="PD\AppBundle\Entity\Caja")
      * @GRID\Column(field="caja.juego.nombre", title="Juego")
      * @GRID\Column(field="caja.numero_carton", title="Caja")
     */
    protected $caja;


    /**
     * @var string
     *
     * @ORM\Column(name="correlativo", type="string", length=10)
     * @GRID\Column(title="Correlativo")
     */
    private $correlativo;

    /** 
      * @ORM\ManyToOne(targetEntity="PD\AppBundle\Entity\Usuario") 
      * @ORM\JoinColumn(name="vendedor_id", referencedColumnName="id", nullable=true)
      * @Assert\Type(type="PD\AppBundle\Entity\Usuario")
      * @GRID\Column(field="vendedor.nombre", title="Nombre vendedor")
      * @GRID\Column(field="vendedor.apellidos", title="Apellidos vendedor")
     */
    protected $vendedor;

    /** @ORM\Column(name="precio_al_vendedor", type="decimal", scale=2) */
    protected $precio_al_vendedor;

    /** @ORM\Column(name="precio_acumulado", type="decimal", scale=2) 
      * @GRID\Column(title="Precio acumulado")
    */
    protected $precio_acumulado;

    /** @ORM\Column(name="premio_acumulado", type="decimal", scale=2) 
      * @GRID\Column(title="Premio acumulado")
    */
    protected $premio_acumulado;

    /**
     * @ORM\Column(type="datetime", nullable=true) 
     */
    protected $fecha_asignacion_vendedor;

    /**
     * @ORM\Column(type="datetime", nullable=true) 
     */
    protected $fecha_estado_final;

    /**
     * @ORM\OneToMany(targetEntity="PD\AppBundle\Entity\Ticket", mappedBy="libreta", cascade={"persist"})
     */
    protected $tickets;

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

    /**
     * Set correlativo
     *
     * @param string $correlativo
     * @return Libreta
     */
    public function setCorrelativo($correlativo)
    {
        $this->correlativo = $correlativo;

        return $this;
    }

    /**
     * Get correlativo
     *
     * @return string 
     */
    public function getCorrelativo()
    {
        return $this->correlativo;
    }

    /**
     * Set precio_al_vendedor
     *
     * @param string $precioAlVendedor
     * @return Libreta
     */
    public function setPrecioAlVendedor($precioAlVendedor)
    {
        $this->precio_al_vendedor = $precioAlVendedor;

        return $this;
    }

    /**
     * Get precio_al_vendedor
     *
     * @return string 
     */
    public function getPrecioAlVendedor()
    {
        return $this->precio_al_vendedor;
    }

    /**
     * Set precio_acumulado
     *
     * @param string $precioAcumulado
     * @return Libreta
     */
    public function setPrecioAcumulado($precioAcumulado)
    {
        $this->precio_acumulado = $precioAcumulado;

        return $this;
    }

    /**
     * Get precio_acumulado
     *
     * @return string 
     */
    public function getPrecioAcumulado()
    {
        return $this->precio_acumulado;
    }

    /**
     * Set fecha_asignacion_vendedor
     *
     * @param \DateTime $fechaAsignacionVendedor
     * @return Libreta
     */
    public function setFechaAsignacionVendedor($fechaAsignacionVendedor)
    {
        $this->fecha_asignacion_vendedor = $fechaAsignacionVendedor;

        return $this;
    }

    /**
     * Get fecha_asignacion_vendedor
     *
     * @return \DateTime 
     */
    public function getFechaAsignacionVendedor()
    {
        return $this->fecha_asignacion_vendedor;
    }

    /**
     * Set fecha_estado_final
     *
     * @param \DateTime $fechaEstadoFinal
     * @return Libreta
     */
    public function setFechaEstadoFinal($fechaEstadoFinal)
    {
        $this->fecha_estado_final = $fechaEstadoFinal;

        return $this;
    }

    /**
     * Get fecha_estado_final
     *
     * @return \DateTime 
     */
    public function getFechaEstadoFinal()
    {
        return $this->fecha_estado_final;
    }

    /**
     * Set vendedor
     *
     * @param \PD\AppBundle\Entity\Usuario $vendedor
     * @return Libreta
     */
    public function setVendedor(\PD\AppBundle\Entity\Usuario $vendedor = null)
    {
        $this->vendedor = $vendedor;

        return $this;
    }

    /**
     * Get vendedor
     *
     * @return \PD\AppBundle\Entity\Usuario 
     */
    public function getVendedor()
    {
        return $this->vendedor;
    }

    /**
     * Set caja
     *
     * @param \PD\AppBundle\Entity\Caja $caja
     * @return Libreta
     */
    public function setCaja(\PD\AppBundle\Entity\Caja $caja = null)
    {
        $this->caja = $caja;

        return $this;
    }

    /**
     * Get caja
     *
     * @return \PD\AppBundle\Entity\Caja 
     */
    public function getCaja()
    {
        return $this->caja;
    }

    /**
     * Constructor
     */
    public function __construct()
    {
        $this->tickets = new \Doctrine\Common\Collections\ArrayCollection();
        //$this->caja = new \Doctrine\Common\Collections\ArrayCollection();
    }

    /**
     * Add tickets
     *
     * @param \PD\AppBundle\Entity\Ticket $tickets
     * @return Libreta
     */
    public function addTicket(\PD\AppBundle\Entity\Ticket $tickets)
    {
        //$this->tickets[] = $tickets;

        $tickets->setLibreta($this);

        $this->tickets->add($tickets);

        return $this;
    }

    /**
     * Remove tickets
     *
     * @param \PD\AppBundle\Entity\Ticket $tickets
     */
    public function removeTicket(\PD\AppBundle\Entity\Ticket $tickets)
    {
        $this->tickets->removeElement($tickets);
    }

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

    public function __toString()
    {
        return $this->correlativo;
    }

    /**
     * Set premio_acumulado
     *
     * @param string $premioAcumulado
     * @return Libreta
     */
    public function setPremioAcumulado($premioAcumulado)
    {
        $this->premio_acumulado = $premioAcumulado;

        return $this;
    }

    /**
     * Get premio_acumulado
     *
     * @return string 
     */
    public function getPremioAcumulado()
    {
        return $this->premio_acumulado;
    }
}

Any ideas how to solve this in order to do this more effective.


I dont know if aplies , shooting in the dark here. But remember relationships in doctrine have an owning side.

Take THAT into account cause as is said in the doc

Changes made only to the inverse side of an association are ignored. Make sure to update both sides of a bidirectional association (or at least the owning side, from Doctrine’s point of view)

This doc has some information about it i think it will help you. Hope it helps you at least


I found some info here

Doctrine2 ORM doesn't refresh objects that are altered outside of a script

I needed to use $em->refresh($caja); after the foreach statement. That solved my problem.

foreach ($caja->getLibretas() as $libreta) {
    $libreta->setCaja(NULL);
    $em->remove($libreta);
}

$em->refresh($caja);
$caja->setEstado('DESHABILITADO');
$em->persist($caja);
$em->flush();