2012-08-10 17 views
6

Estoy trabajando en un proyecto de CodeIgniter en el que estoy usando Doctrine2 y el componente Symfony2 Validator.Problema al importar anotaciones

Todas mis entidades de Doctrine2 use Doctrine\ORM\Mapping y el administrador de entidades las reconocen. Mi anotación de entidad tiene este aspecto:

/** 
* @Entity(repositoryClass = "UserRepository") 
* @Table(name = "user") 
* @HasLifecycleCallbacks() 
*/ 

En este punto, puedo persistir las entidades sin ningún problema. El primer problema surge cuando intento usar el componente Symfony2 Validator. Cuando intento de validar un objeto User, me sale este error:

[Semantical Error] The annotation "@Entity" in class Entity\User was never imported. Did you maybe forget to add a "use" statement for this annotation?

La única "solución" a este problema es a través de use Doctrine\Mapping\Entity, pero tengo que hacer eso por cada anotación siendo utilizado por mi entidad (Tabla, Columna, ManyToOne, etc.). Estoy tratando de averiguar por qué necesito explícitamente use cada clase de anotación en lugar de que se reconozcan automáticamente (¿no debería use Doctrine\ORM\Mapping otorgarme acceso a todas las clases dentro de ese espacio de nombres?).

Entonces, probé use Doctrine\ORM\Mapping as ORM y prefacio todas mis anotaciones con ORM\. Ej: @ORM\Entity(). El validador Symfony2 deja de quejarse, pero ahora Doctrine2 se queja de que Class Entity\User is not a valid entity or mapped super class. no tengo idea de por qué este método funciona para el Validator, pero no para Doctrine2. Si ejecuto el comando de consola doctrine:orm:info, no se reconoce mi entidad User.

Como esta es una aplicación CodeIgniter, estoy cargando automáticamente las bibliotecas Symfony2 y Doctrine2. Mi código de carga automática es el siguiente:

# Symfony2 ClassLoader component 
require_once __DIR__ . '/application/libraries/symfony/src/Symfony/Component/ClassLoader/UniversalClassLoader.php'; 
$loader = new \Symfony\Component\ClassLoader\UniversalClassLoader(); 
$loader->register(); 
$loader->registerNamespace('Symfony', __DIR__ . '/application/libraries/symfony/src'); 
$loader->registerNamespace('Doctrine', __DIR__ . '/application/libraries/doctrine/lib'); 

# Doctrine2 
require_once __DIR__ . '/application/libraries/doctrine/lib/Doctrine/Common/Annotations/AnnotationRegistry.php'; 
use Doctrine\Common\Annotations\AnnotationRegistry; 
AnnotationRegistry::registerLoader(function($class) use ($loader) { 
    $loader->loadClass($class); 
    $classExists = class_exists($class, false); 
    return $classExists; 
}); 
AnnotationRegistry::registerFile(__DIR__ . '/application/libraries/doctrine/lib/Doctrine/ORM/Mapping/Driver/DoctrineAnnotations.php'); 

No me importa si tengo que incondicional todo con ORM\ o no, yo sólo quiero encontrar una solución que el validador de Symfony2 y Doctrine2 los dos para trabajar con ellos. ¿Algunas ideas?

Respuesta

19

Tuve un problema similar al usar Silex, Doctrine2 y Symfony-Validator.

La solución fue evitar el uso del SimpleAnnotationsReader y, en su lugar, utilizar el AnnotationReader normal (echar un vistazo a Doctrine\ORM\Configuration::newDefaultAnnotationDriver). Luego puede preceder a cada entidad con ORM\ (y, por supuesto, insertando use Doctrine\ORM\Mapping as ORM; en cada entidad).

+0

Qué pasa con el caso en el que trabajó sin 'ORM \' por lo que codificado todas las entidades de esa manera, ahora, de repente, se dejado de funcionar sin razón y nos queda una pesadilla de mantenimiento? – Brandon

3

Agregue use declaraciones para cada anotación que ha usado en su entities. por ejemplo:

use Doctrine\ORM\Mapping\Entity; 
use Doctrine\ORM\Mapping\Table; 
use Doctrine\ORM\Mapping\Id; 
use Doctrine\ORM\Mapping\Column; 
use Doctrine\ORM\Mapping\GeneratedValue; 

Pero puede que no te interese usar este método. Puede escribir todas las declaraciones use en un archivo y solo incluirlo en su entities.

+3

'use Doctrine \ ORM \ Mapping as ORM;' le permite usar '@ORM \ Entity', etc. que es mucho más conciso. user1825294 lo tiene correcto. – konrad

+0

Sí, tiene usted razón, gracias –

+0

¡Esta no es la solución que desea! Ni lo que tendrá con las anotaciones. –

6

que resuelven este problema agregando lo siguiente a mi archivo de la entidad:

use Doctrine\ORM\Mapping as ORM; 

Así que mi archivo ahora se ve así:

<?php 

namespace Acme\CustomBundle\Entity; 

use Doctrine\ORM\Mapping as ORM; 

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

    /** 
    * @ORM\Column(type="string", length=125) 
    * 
    * @var string 
    */ 
    private $title; 

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

    /** 
    * Set title 
    * 
    * @param string $title 
    * 
    * @return Example 
    */ 
    public function setTitle($title) 
    { 
     $this->title = $title; 

     return $this; 
    } 

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

} 
+0

Esto no funcionó para la necesidad específica de la anotación de identificación. Tuve que especificarlo individualmente como se mostraba la respuesta de @ Mostafa. – Jestep

0

Si está probando y sus pruebas fallan debido a esto. Asegúrate de tener configurada la función de autocarga correcta en tu configuración de phpunit.

Para un escenario muy específico, mi problema fue actualizar mi versión de Symfony que, antes de que tuviera el archivo bootstrap.cache.php, pero en una nueva versión, es app/autoload. Tuve que cambiar mi fichero de configuración phpunit.xml y establecer mi opción de arranque a ese archivo bootstrap="autoload.php"

Cuestiones relacionadas