Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Doctrine 2 - No Metadata Classes to process by orm:generate-repositories

I'm trying to generate entity repositories and getting such message

No Metadata Classes to process

I'd tracked down that use of

use Doctrine\ORM\Mapping as ORM; and @ORM\Table is not working properly.

If i change all @ORM\Table to just @Table(and other annotations) - it start to work, but I really don't want to get it that way as it should work with @ORM annotation.

I followed instructions from page below with no luck. I know I'm close but missing something with file paths or namespaces. Please help.

http://docs.doctrine-project.org/projects/doctrine-common/en/latest/reference/annotations.html

Does anyone had such problem? What I missing?

cli-config,

use Doctrine\Common\Annotations\AnnotationReader;
use Doctrine\Common\Annotations\AnnotationRegistry;

require_once 'Doctrine/Common/ClassLoader.php';

define('APPLICATION_ENV', "development");
error_reporting(E_ALL);



//AnnotationRegistry::registerFile("Doctrine/ORM/Mapping/Driver/DoctrineAnnotations.php");
//AnnotationRegistry::registerAutoloadNamespace("Symfony\Component\Validator\Constraint", "Doctrine/Symfony");
//AnnotationRegistry::registerAutoloadNamespace("Annotations", "/Users/ivv/workspaceShipipal/shipipal/codebase/application/persistent/");

$classLoader = new \Doctrine\Common\ClassLoader('Doctrine');
$classLoader->register();

$classLoader = new \Doctrine\Common\ClassLoader('Entities', __DIR__ . '/application/');
$classLoader->register();
$classLoader = new \Doctrine\Common\ClassLoader('Proxies', __DIR__ . '/application/persistent');
$classLoader->register();

$config = new \Doctrine\ORM\Configuration();
$config->setProxyDir(__DIR__ . '/application/persistent/Proxies');
$config->setProxyNamespace('Proxies');

$config->setAutoGenerateProxyClasses((APPLICATION_ENV == "development"));


$driverImpl = $config->newDefaultAnnotationDriver(array(__DIR__ . "/application/persistent/Entities"));
$config->setMetadataDriverImpl($driverImpl);

if (APPLICATION_ENV == "development") {
    $cache = new \Doctrine\Common\Cache\ArrayCache();
} else {
    $cache = new \Doctrine\Common\Cache\ApcCache();
}

$config->setMetadataCacheImpl($cache);
$config->setQueryCacheImpl($cache);


$connectionOptions = array(
    'driver'   => 'pdo_mysql',
    'host'     => '127.0.0.1',
    'dbname'   => 'mydb',
    'user'     => 'root',
    'password' => ''

);

$em = \Doctrine\ORM\EntityManager::create($connectionOptions, $config);
$platform = $em->getConnection()->getDatabasePlatform();
$platform->registerDoctrineTypeMapping('enum', 'string');

$helperSet = new \Symfony\Component\Console\Helper\HelperSet(array(
     'db' => new \Doctrine\DBAL\Tools\Console\Helper\ConnectionHelper($em->getConnection()),
     'em' => new \Doctrine\ORM\Tools\Console\Helper\EntityManagerHelper($em)
));

User.php(working version, initially it was as described, @Table was @ORM\Table and other annotations similar had @ORM\ part like @ORM\Column etc)

<?php
namespace Entities;


use Doctrine\Mapping as ORM;

/**
 * User
 *
 * @Table(name="user")
 * @Entity(repositoryClass="Repository\User")
 */
class User
{
    /**
     * @var integer $id
     *
     * @Column(name="id", type="integer", nullable=false)
     * @Id
     * @GeneratedValue
     */
    private $id;

    /**
     * @var string $userName
     *
     * @Column(name="userName", type="string", length=45, nullable=false)
     */
    private $userName;

    /**
     * @var string $email
     *
     * @Column(name="email", type="string", length=45, nullable=false)
     */
    private $email;

    /**
     * @var text $bio
     *
     * @Column(name="bio", type="text", nullable=true)
     */
    private $bio;

    public function __construct()
    {

    }

}
like image 277
waney Avatar asked Mar 18 '12 02:03

waney


2 Answers

EDIT 3:

If it matters, I'm using Doctrine 2.2.1. Anyway, I'm just adding a bit more information on this topic.

I dug around the Doctrine\Configuration.php class to see how newDefaultAnnotationDriver created the AnnotationDriver. The method begins on line 125, but the relevant part is line 145 to 147 if you're using the latest version of the Common library.

} else {
    $reader = new AnnotationReader();
    $reader->setDefaultAnnotationNamespace('Doctrine\ORM\Mapping\\');
}

I couldn't actually find the setDefaultAnnotationNamespace method in AnnotationReader class. So that was weird. But I'm assuming it sets the namespace Doctrine\Orm\Mapping, so that annotations in that namespace don't need to be prefixed. Hence the error since it seems the doctrine cli tool generates the entities differently. I'm not sure why that is.

You'll notice in my answer below, I didn't call the setDefaultAnnotationNamespace method.

One a side note, I noticed in your User Entity class that you have use Doctrine\Mapping as ORM. Shouldn't the generated file create use Doctrine\Orm\Mapping as ORM;? Or maybe that is a typo.

EDIT 1: Ok, I found the problem. Apparently it has to do with the default annotation driver used by the \Doctrine\ORM\Configuration class.

So instead of using $config->newDefaultAnnotationDriver(...), you need to instantiate a new AnnotationReader, a new AnnotationDriver, and then set it in your Configuration class.

Example:

AnnotationRegistry::registerFile("Doctrine/ORM/Mapping/Driver/DoctrineAnnotations.php");
$reader = new AnnotationReader();
$driverImpl = new \Doctrine\ORM\Mapping\Driver\AnnotationDriver($reader, array(__DIR__ . "/application/persistent/Entities"));
$config->setMetadataDriverImpl($driverImpl);

EDIT2 (Here the adjustments added to your cli-config.php):

use Doctrine\Common\Annotations\AnnotationReader;
use Doctrine\Common\Annotations\AnnotationRegistry;

require_once 'Doctrine/Common/ClassLoader.php';

define('APPLICATION_ENV', "development");
error_reporting(E_ALL);

$classLoader = new \Doctrine\Common\ClassLoader('Doctrine');
$classLoader->register();

$classLoader = new \Doctrine\Common\ClassLoader('Entities', __DIR__ . '/application/');
$classLoader->register();
$classLoader = new \Doctrine\Common\ClassLoader('Proxies', __DIR__ . '/application/persistent');
$classLoader->register();

$config = new \Doctrine\ORM\Configuration();
$config->setProxyDir(__DIR__ . '/application/persistent/Proxies');
$config->setProxyNamespace('Proxies');

$config->setAutoGenerateProxyClasses((APPLICATION_ENV == "development"));


 //Here is the part that needs to be adjusted to make allow the ORM namespace in the annotation be recognized

#$driverImpl = $config->newDefaultAnnotationDriver(array(__DIR__ . "/application/persistent/Entities"));

AnnotationRegistry::registerFile("Doctrine/ORM/Mapping/Driver/DoctrineAnnotations.php");
$reader = new AnnotationReader();
$driverImpl = new \Doctrine\ORM\Mapping\Driver\AnnotationDriver($reader, array(__DIR__ . "/application/persistent/Entities"));
$config->setMetadataDriverImpl($driverImpl);

//End of Changes

if (APPLICATION_ENV == "development") {
    $cache = new \Doctrine\Common\Cache\ArrayCache();
} else {
   $cache = new \Doctrine\Common\Cache\ApcCache();
}

$config->setMetadataCacheImpl($cache);
$config->setQueryCacheImpl($cache);


$connectionOptions = array(
    'driver'   => 'pdo_mysql',
    'host'     => '127.0.0.1',
    'dbname'   => 'mydb',
    'user'     => 'root',
    'password' => ''
);

$em = \Doctrine\ORM\EntityManager::create($connectionOptions, $config);
$platform = $em->getConnection()->getDatabasePlatform();
$platform->registerDoctrineTypeMapping('enum', 'string');

$helperSet = new \Symfony\Component\Console\Helper\HelperSet(array(
    'db' => new \Doctrine\DBAL\Tools\Console\Helper\ConnectionHelper($em->getConnection()),
    'em' => new \Doctrine\ORM\Tools\Console\Helper\EntityManagerHelper($em)
));
like image 68
Gohn67 Avatar answered Oct 31 '22 15:10

Gohn67


I just ran into the same problem that you've got. I am using Doctrine 2.4. I can fix this issue by doing this in the config file. I am not sure if this works for versions < 2.3.

$config = Setup::createAnnotationMetadataConfiguration(array(__DIR__."/src/entities"), $isDevMode, null, null, FALSE); // just add null, null, false at the end

Below is the documentation for the method createAnnotationMetadataConfiguration. I have just dig into the source code. By default it uses a simple annotation reader, which means you don't need to have ORM\ in front of your annotation, you can do @Entities instead of @ORM\Entities. So all you need to do here is to disable it using simple annotation reader.

/**
 * Creates a configuration with an annotation metadata driver.
 *
 * @param array   $paths
 * @param boolean $isDevMode
 * @param string  $proxyDir
 * @param Cache   $cache
 * @param bool    $useSimpleAnnotationReader
 *
 * @return Configuration
 */
public static function createAnnotationMetadataConfiguration(array $paths, $isDevMode = false, $proxyDir = null, Cache $cache = null, $useSimpleAnnotationReader = true)
like image 10
Zorji Avatar answered Oct 31 '22 14:10

Zorji