Carlos Robles frikiblog

Doctrine 2 ReflectionException – class does not exist

| 0 comments

Cuando estamos trabajando con clases con anotaciones en doctrine 2, dentro de Zend Framework 2, si una clase tiene un campo que hace referencia a otra entidad (una relación manyToOne, ManyToMany, o lo que sea) y esa entidad, tiene otro campo que hace referencia a una tercera entidad, lo más normal es que tengamos problemas.

Esto es porque al parecer, los namespaces no viajan bien por todas las funciones que utiliza el ORM para cargar las clases necesarias y crear los objetos, si no lo especificamos correctamente. Si hemos creado nuestras clases a través de ingeniería inversa, puede que doctrine no nos haya creado los parámetros de la mejor forma posible si estamos trabajando con namespaces propios (que es lo más habitual), y por tanto hará falta un poco de retoque.

Por ejemplo, si tenemos una tabla localidad, con una columna provincia, que hace es clave externa, doctrine nos crearía una entidad como la que pongo a continuación. Para englobar todas entidades utilizo DBAL\Entity

<?php
 namespace DBAL\Entity;

use Doctrine\ORM\Mapping as ORM;

/**
 * GeoLocalidad
 *
 * @ORM\Table(name="geo_localidad")
 * @ORM\Entity
 */
class GeoLocalidad
{
 /**
 * @var string
 *
 * @ORM\Column(name="nombre", type="string", length=45, nullable=true)
 */
 private $nombre;

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

 /**
 * @var \GeoProvincia
 *
 * @ORM\ManyToOne(targetEntity="GeoProvincia")
 * @ORM\JoinColumns({
 * @ORM\JoinColumn(name="provincia", referencedColumnName="id")
 * })
 */
 private $provincia;

 /**
 * Set nombre
 *
 * @param string $nombre
 * @return GeoLocalidad
 */
 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;
 }

 /**
 * Set provincia
 *
 * @param \GeoProvincia $provincia
 * @return GeoLocalidad
 */
 public function setProvincia(\GeoProvincia $provincia = null)
 {
 $this->provincia = $provincia;

 return $this;
 }

 /**
 * Get provincia
 *
 * @return \GeoProvincia
 */
 public function getProvincia()
 {
 return $this->provincia;
 }

   }
 

en esta clase, el error nos lo estaría generando la funcion:

/**
 * Set provincia
 *
 * @param \GeoProvincia $provincia
 * @return GeoLocalidad
 */
public function setProvincia(\GeoProvincia $provincia = null)

Y lo solucionaríamos cambiando el tipo \GeoProvincia, de forma que indicasemos el namespace completo, pero solo en el parámetro, no hace falta que lo cambiemos en la anotacion. Si el namespace de provincia, igual que el de localidad es DBAL\Entity la función quedaría con esta forma:

/**
 * Set provincia
 *
 * @param \GeoProvincia $provincia
 * @return GeoLocalidad
 */
public function setProvincia(\DBAL\Entity\GeoProvincia $provincia = null)

y ojo al \ inicial!

Tambien lo podemos hacer quitando por completo el namespace, dejando la función quedaría de esta forma:

/**
 * Set provincia
 *
 * @param \GeoProvincia $provincia
 * @return GeoLocalidad
 */
public function setProvincia( GeoProvincia $provincia = null)

 
tomando esta medida en todas las clases implicadas, todo funcionará perfectamente.

Facebook Twitter Linkedin Plusone Digg Delicious Reddit Email

Leave a Reply

Required fields are marked *.