I'm working on a CodeIgniter project in which I'm using Doctrine2 and the Symfony2 Validator component.
All my Doctrine2 entities use Doctrine\ORM\Mapping
and the entity manager recognizes them. My entity annotation looks like this:
/**
* @Entity(repositoryClass = "UserRepository")
* @Table(name = "user")
* @HasLifecycleCallbacks()
*/
At this point, I'm able to persist entities without any trouble. The first problem arises when I try to use the Symfony2 Validator component. When I try to validate a User
object, I get this 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?
The only "fix" to this issue is through use Doctrine\Mapping\Entity
, but I have to do that for every annotation being used by my entity (Table, Column, ManyToOne, etc.). I'm trying to figure out why I need to explicitely use
each annotation class instead of them being automatically recognized (shouldn't use Doctrine\ORM\Mapping
grant me access to all the classes within that namespace?).
So, I then tried use Doctrine\ORM\Mapping as ORM
and prefacing all my annotations with ORM\
. Ex: @ORM\Entity()
. The Symfony2 validator stops complaining, but now Doctrine2 complains that Class Entity\User is not a valid entity or mapped super class.
I have no idea why this method works for the Validator, but not Doctrine2. If I run the console command doctrine:orm:info
, my User
entity is not recognized.
Because this is a CodeIgniter app, I'm autoloading the Symfony2 and Doctrine2 libraries. My autoload code is as follows:
# 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');
I don't care if I have to preface everything with ORM\
or not, I just want to find a solution that the Symfony2 Validator and Doctrine2 will both work with. Any ideas?
I had a similar issue when using Silex, Doctrine2 and the Symfony-Validator.
The solution was to avoid using the SimpleAnnotationsReader and instead using the normal AnnotationReader (have a look at Doctrine\ORM\Configuration::newDefaultAnnotationDriver). You can then preface every entity with ORM\
(and of course inserting use Doctrine\ORM\Mapping as ORM;
in every entity).
Add use
statements for every annotation you have used in your entities
. for example:
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;
But you may not interesting to use this method. You can write all use
statements to one file and just include it in your entities
.
I resolved this issue by adding the following to my entity file:
use Doctrine\ORM\Mapping as ORM;
So my file now looks like:
<?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;
}
}
If you are testing and your tests fail because of this. Make sure you have the right autoload configured in your phpunit settings.
For a very specific scenario, my problem was upgrading my symfony version whereas before i had the bootstrap.cache.php
file, but on a new version, it is app/autoload
. I had to change my phpunit.xml
config file and set my bootstrap option to that file bootstrap="autoload.php"
I was getting the same error message "[Semantical Error] The annotation "@Entity" in class Entity\User was never imported. Did you maybe forget to add a "use" statement for this annotation?".
The problem was that I had alias for ORM and did not used it for the annotation.
I had this: @OneToOne(targetEntity="CompanyProduct")
And correct was this: @ORM\OneToOne(targetEntity="CompanyProduct")
My problem solved by adding:
use Doctrine\ORM\Mapping\HasLifecycleCallbacks;