Doctrine 2 - ORM
  1. Doctrine 2 - ORM
  2. DDC-1141

DisconnectedClassMetadataFactory forbids direct XML-to-SQL conversion

    Details

    • Type: Bug Bug
    • Status: Resolved
    • Priority: Minor Minor
    • Resolution: Fixed
    • Affects Version/s: Git Master
    • Fix Version/s: 2.1
    • Component/s: Tools
    • Security Level: All
    • Labels:
      None

      Description

      Doctrine\ORM\Tools\DisconnectedClassMetadataFactory::newClassMetadataInstance() returns instances of ClassMetadataInfo, while the parent returns instances of ClassMetadata. This creates problems when using SchemaTool to create a schema from an XML mapping for instance:

      Fatal error: Call to undefined method Doctrine\ORM\Mapping\ClassMetadataInfo::getQuotedTableName() 
      in path/to/Doctrine/ORM/Tools/SchemaTool.php on line 133
      

      This is because schemaTool expects ClassMetadata objects, while it got ClassMetadataInfo objects.

      My setup:

       
      $config = new Configuration();
      $config->setMetadataCacheImpl(new \Doctrine\Common\Cache\ArrayCache);
      $driverImpl = new XmlDriver(__DIR__ . '/fixtures');
      $config->setMetadataDriverImpl($driverImpl);
      $config->setProxyDir(__DIR__ . '/Proxies');
      $config->setProxyNamespace('Proxies');
      $connectionOptions = array(
          'driver' => 'pdo_sqlite',
          'path' => 'database.sqlite'
      );
      $em = \Doctrine\ORM\EntityManager::create($connectionOptions, $config);
      $cmf = new DisconnectedClassMetadataFactory();
      $cmf->setEntityManager($em);
      
      $metadatas = $cmf->getAllMetadata() // array of ClassMetadataInfo and not ClassMetadata
      

      I think Doctrine\ORM\Tools\DisconnectedClassMetadataFactory::newClassMetadataInstance() should return a ClassMetadata instance.

        Activity

        Hide
        Francois Zaninotto added a comment -

        Ok, the proposed solution is wrong.

        I actually need an array of ClassMetadataInfo and not of ClassMetadata, since the entities don't exist (yet). So the problem lies in the fact that getQuotedTableName() and getQuotedColumnName() are methods of Doctrine\ORM\Mapping\ClassMetadata, and not of Doctrine\ORM\Mapping\ClassMetadataInfo. Moving these two methods up the inheritance path, I managed to create a schema directly from an XML mapping. However, I had to inject the MetadataFactory inside the EM, otherwise the SchemaTool coped when dealing wit hrelationships.

        So a working setup to generate SQL from an XML mapping without stepping by Entity generation is:

        $config = new Configuration();
        $config->setMetadataCacheImpl(new \Doctrine\Common\Cache\ArrayCache);
        $driverImpl = new XmlDriver(__DIR__ . '/fixtures');
        $config->setMetadataDriverImpl($driverImpl);
        $config->setProxyDir(__DIR__ . '/Proxies');
        $config->setProxyNamespace('Proxies');
        $config->setClassMetadataFactoryName('Doctrine\ORM\Tools\DisconnectedClassMetadataFactory');
        $connectionOptions = array(
            'driver' => 'pdo_sqlite',
            'path' => 'database.sqlite'
        );
        $em = \Doctrine\ORM\EntityManager::create($connectionOptions, $config);
        $cmf = $em->getMetadataFactory();
        
        $schemaTool = new SchemaTool($em);
        $schemaTool->createSchema($cmf->getAllMetadata());
        

        But again, this requires moving up the two methods from ClassMetadata to ClassMetadataInfo.

        Show
        Francois Zaninotto added a comment - Ok, the proposed solution is wrong. I actually need an array of ClassMetadataInfo and not of ClassMetadata, since the entities don't exist (yet). So the problem lies in the fact that getQuotedTableName() and getQuotedColumnName() are methods of Doctrine\ORM\Mapping\ClassMetadata, and not of Doctrine\ORM\Mapping\ClassMetadataInfo. Moving these two methods up the inheritance path, I managed to create a schema directly from an XML mapping. However, I had to inject the MetadataFactory inside the EM, otherwise the SchemaTool coped when dealing wit hrelationships. So a working setup to generate SQL from an XML mapping without stepping by Entity generation is: $config = new Configuration(); $config->setMetadataCacheImpl( new \Doctrine\Common\Cache\ArrayCache); $driverImpl = new XmlDriver(__DIR__ . '/fixtures'); $config->setMetadataDriverImpl($driverImpl); $config->setProxyDir(__DIR__ . '/Proxies'); $config->setProxyNamespace('Proxies'); $config->setClassMetadataFactoryName('Doctrine\ORM\Tools\DisconnectedClassMetadataFactory'); $connectionOptions = array( 'driver' => 'pdo_sqlite', 'path' => 'database.sqlite' ); $em = \Doctrine\ORM\EntityManager::create($connectionOptions, $config); $cmf = $em->getMetadataFactory(); $schemaTool = new SchemaTool($em); $schemaTool->createSchema($cmf->getAllMetadata()); But again, this requires moving up the two methods from ClassMetadata to ClassMetadataInfo.
        Hide
        Benjamin Eberlei added a comment -

        Moving the methods up is the solution i guess, however i have to think why we did this in the first place, probably because of dependencies.

        Show
        Benjamin Eberlei added a comment - Moving the methods up is the solution i guess, however i have to think why we did this in the first place, probably because of dependencies.
        Hide
        Benjamin Eberlei added a comment -

        This was merged into Doctrine 2.1 / master

        Show
        Benjamin Eberlei added a comment - This was merged into Doctrine 2.1 / master

          People

          • Assignee:
            Benjamin Eberlei
            Reporter:
            Francois Zaninotto
          • Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved: