Search code examples
mysqldoctrine-ormone-to-manymany-to-onehydration

doctrine2, retrieve associated data from inverse side


I have 2 entities. The simple logic is that a user has many delivery address, so in the future they will be able to choose one of them for their deliveries.

First entity, Direccion (address).

<?php 

use Doctrine\ORM\Mapping as ORM;

/**
 * Direccion
 *
 * @ORM\Table(name="direccion", indexes={@ORM\Index(name="id_usuario", 
columns={"id_usuario"})})
 * @ORM\Entity
 */
class Direccion
{
    /**
     * @var string
     *
     * @ORM\Column(name="Calle", type="string", length=100, nullable=false)
     */
    private $calle;        

    /**
     * @var integer
     *
     * @ORM\Column(name="id", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="IDENTITY")
     */
    private $id;

    /**
     * @var \Usuario
     *
     * @ORM\ManyToOne(targetEntity="Usuario", inversedBy="direcciones",  fetch="EAGER")
     * @ORM\JoinColumns({
     *   @ORM\JoinColumn(name="id_usuario", referencedColumnName="id" )
     * })
     */
    private $idUsuario;


    /**
     * Set calle
     *
     * @param string $calle
     * @return Direccion
     */
    public function setCalle($calle)
    {
        $this->calle = $calle;

        return $this;
    }

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

    
    /**
     * Set idUsuario
     *
     * @param \Usuario $idUsuario
     * @return Direccion
     */
    public function setIdUsuario(\Usuario $idUsuario = null)
    {
        $this->idUsuario = $idUsuario;

        return $this;
    }

    /**
     * Get idUsuario
     *
     * @return \Usuario 
     */
    public function getIdUsuario()
    {
        return $this->idUsuario;
    }

}

and the second entity is, Usuario (User)

<?php



use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\ArrayCollection;
/**
 * Usuario
 *
 * @ORM\Table(name="usuario")
 * @ORM\Entity
 */
class Usuario
{


    /**
     * @var string
     *
     * @ORM\Column(name="nombre", type="string", length=255, nullable=true)
     */
    private $nombre;


    /**
     * @var integer
     *
     * @ORM\Column(name="id", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="IDENTITY")
     */
    private $id;


    /**
     * @ORM\OneToMany(targetEntity="Direccion", mappedBy="id_usuario", cascade={"persist"})
     */
    private $direcciones;


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

    

    /**
     * Set nombre
     *
     * @param string $nombre
     * @return Usuario
     */
    public function setNombre($nombre)
    {
        $this->nombre = $nombre;

        return $this;
    }

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

    

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


    public function getDirecciones()
    {
        return $this->direcciones;
    }

    public function setDirecciones($direcciones)
    {
        $this->direcciones = $direcciones;

        return $this;
    }



}

I have already read many blogs and similar questions, but I can't get the property $direcciones hydrated or filled with the associated data, when I try to achieve that on the inverse side of the relation (OneToMany), with $usuario->getDirecciones();

I'm working in with this code in a non MVC architecture, to this point everything works like charm in getting creating and updating through a DAO which uses the Doctrine sentences, so I know that in the ending points (updating, creating, persist and flush, retrieving data with find, findBy, etc.), everything works fine.

When I try to fill the ArrayCollection calling from the Service layer where I use both classes (Usuario-InverseSide and Direccion-OwnerSide), nothing happens, the $direcciones arrayCollection property on Usuario instance, doesn't fetch anything, even when I tried establishing fetch="EAGER"on the annotations.

for the rest of the data or properties, everything works fine, all the other attributes of the user get filled just fine.

For some reason, the annotations are not being considered, don´t know why. I've spent a few days trying to figure out how to accomplish this way of accessing the associated data, didn't wanted to use DQL, but at this point I think I will take that road.

I tried something hard-coded to test and, the result is the same, $direcciones doesn't get his data.Obvious are already discarded, that exact ID for a Usuario(user) has his related direcciones(address) setted.

$usuario = $this->usuarioDAO->find(20);
        $direcciones = $usuario->getDirecciones();
        var_dump($direcciones);
        return $usuario;

the relation was only defined with a FK called id_usuario on Direccion on a MySQL InnoDb table.

don't know if I should be setting something else on the Usuario table. or if there is something wrong in the way I store the entities on my project.

please help me, any recommendation will be appreciated.

doctrine 2, how do get data from the inverse side (many to one)


Solution

  • i resolved it.

    happens that for some reason, the php annotations were not being actually readed, or on a different way to say it, it was listening to the XML annotations first, so i put the xml sentence on the inverse side of the relation (usuario) inside the tags

    <one-to-many field="direcciones" target-entity="Direccion" mapped-by="idUsuario" />
    

    and it worked, now i got polish the data result of the consult so i can send a cleaner/clearer object to the front-end.