DDC-616: Reverse engineering with Oracle #757

Closed
opened 2026-01-22 12:49:23 +01:00 by admin · 6 comments
Owner

Originally created by @doctrinebot on GitHub (May 29, 2010).

Originally assigned to: @beberlei on GitHub.

Jira issue originally created by user mikaelkael:

I am playing with reverse engineering with Oracle and I have some problems:

My schema:

create table TABLE_TEST1 (
   TEST1*FIRST*COLUMN      NUMBER(4)                       not null,
   TEST1*SECOND*COLUMN     VARCHAR2(50)                    not null,
   TEST1*THIRD*COLUMN      DATE,
   constraint PK*TABLE_TEST1 primary key (TEST1_FIRST*COLUMN)
         using index
       tablespace TBS_INDEX
       storage
       (
           initial 100K
           next 100K
       )
)
storage
(
    initial 100K
    next 100K
)
tablespace TBS_DATA;

create table TABLE_TEST2 (
   TEST2*FIRST*COLUMN      NUMBER(4)                       not null,
   TEST2*SECOND*COLUMN     VARCHAR2(50)                    not null,
   TEST2*THIRD*COLUMN      DATE,
   TEST1*FIRST*COLUMN      NUMBER(4)                       not null,
   constraint PK*TABLE_TEST2 primary key (TEST2_FIRST*COLUMN)
         using index
       tablespace TBS_INDEX
       storage
       (
           initial 100K
           next 100K
       )
)
storage
(
    initial 100K
    next 100K
)
tablespace TBS_DATA;

alter table TABLE_TEST2
   add constraint TABLE*TEST2__TABLE_TEST1 foreign key (TEST1_FIRST*COLUMN)
      references TABLE*TEST1 (TEST1_FIRST*COLUMN);

My reverse engineering code:

ini*set('display*errors', 1);
set*include_path(realpath(__DIR_* . '/../doctrine-orm/lib/'));

require 'Doctrine/Common/ClassLoader.php';
$classLoader = new \Doctrine\Common\ClassLoader('Doctrine', realpath(*_DIR_* . '/../doctrine-orm/lib/'));
$classLoader->register();

$config = new \Doctrine\ORM\Configuration;
$cache = new \Doctrine\Common\Cache\ApcCache;
$config->setMetadataCacheImpl($cache);
$driverImpl = $config->newDefaultAnnotationDriver(realpath(*_DIR_*. '/Infofab/Entities'));
$config->setMetadataDriverImpl($driverImpl);
$config->setQueryCacheImpl($cache);
$config->setProxyDir('Proxies');
$config->setProxyNamespace('Infofab');
$connectionOptions = array(
    'dbname' => 'bddmkk',
    'user' => 'doctrine',
    'password' => 'xxxxxxx',
    'host' => 'localhost',
    'driver' => 'pdo_oci',
    'driverOptions' => array(PDO::ATTR*CASE => PDO::CASE*LOWER)
);

$em = \Doctrine\ORM\EntityManager::create($connectionOptions, $config);

$sm = $em->getConnection()->getSchemaManager();

$em->getConfiguration()->setMetadataDriverImpl(
    new \Doctrine\ORM\Mapping\Driver\DatabaseDriver(
        $em->getConnection()->getSchemaManager()
    )
);

$cmf = new \Doctrine\ORM\Tools\DisconnectedClassMetadataFactory($em);
$metadata = $cmf->getAllMetadata();

$cme = new \Doctrine\ORM\Tools\Export\ClassMetadataExporter();
$exporter = $cme->getExporter('annotation', 'Infofab');
$exporter->setMetadata($metadata);
$etg = new \Doctrine\ORM\Tools\EntityGenerator;
$exporter->setEntityGenerator($etg);
$exporter->export();

If I run this code, I obtain 2 entities:

<?php
/****
 * TableTest1
 *
 * @Table(name="TABLE_TEST1")
 * @Entity
 */
class TableTest1
{
    /****
     * @var integer $test1FirstColumn
     *
     * @Column(name="TEST1*FIRST*COLUMN", type="integer", nullable=false)
     * @Id
     * @GeneratedValue(strategy="SEQUENCE")
     * @SequenceGenerator(sequenceName="TABLE*TEST1_TEST1_FIRST*COLUMN", allocationSize="10", initialValue="1")
     */
    private $test1FirstColumn;

    /****
     * @var string $test1SecondColumn
     *
     * @Column(name="TEST1*SECOND*COLUMN", type="string", length=50, nullable=false)
     */
    private $test1SecondColumn;

    /****
     * @var datetime $test1ThirdColumn
     *
     * @Column(name="TEST1*THIRD*COLUMN", type="datetime", nullable=true)
     */
    private $test1ThirdColumn;
}

and

<?php
/****
 * TableTest2
 *
 * @Table(name="TABLE_TEST2")
 * @Entity
 */
class TableTest2
{
    /****
     * @var integer $test2FirstColumn
     *
     * @Column(name="TEST2*FIRST*COLUMN", type="integer", nullable=false)
     * @Id
     * @GeneratedValue(strategy="SEQUENCE")
     * @SequenceGenerator(sequenceName="TABLE*TEST2_TEST2_FIRST*COLUMN", allocationSize="10", initialValue="1")
     */
    private $test2FirstColumn;

    /****
     * @var integer $test1FirstColumn
     *
     * @Column(name="TEST1*FIRST*COLUMN", type="integer", nullable=false)
     */
    private $test1FirstColumn;

    /****
     * @var string $test2SecondColumn
     *
     * @Column(name="TEST2*SECOND*COLUMN", type="string", length=50, nullable=false)
     */
    private $test2SecondColumn;

    /****
     * @var datetime $test2ThirdColumn
     *
     * @Column(name="TEST2*THIRD*COLUMN", type="datetime", nullable=true)
     */
    private $test2ThirdColumn;

    /****
     * @var TABLETEST1
     *
     * @OneToOne(targetEntity="TABLETEST1")
     * @JoinColumns({
     *   @JoinColumn(name="TEST1*FIRST_COLUMN", referencedColumnName="TEST1_FIRST*COLUMN")
     * })
     */
    private $tEST1FIRSTCOLUMN;
}

As you can see, it declares 2 times the same column: private $test1FirstColumn; and private $tEST1FIRSTCOLUMN;

Originally created by @doctrinebot on GitHub (May 29, 2010). Originally assigned to: @beberlei on GitHub. Jira issue originally created by user mikaelkael: I am playing with reverse engineering with Oracle and I have some problems: My schema: ``` create table TABLE_TEST1 ( TEST1*FIRST*COLUMN NUMBER(4) not null, TEST1*SECOND*COLUMN VARCHAR2(50) not null, TEST1*THIRD*COLUMN DATE, constraint PK*TABLE_TEST1 primary key (TEST1_FIRST*COLUMN) using index tablespace TBS_INDEX storage ( initial 100K next 100K ) ) storage ( initial 100K next 100K ) tablespace TBS_DATA; create table TABLE_TEST2 ( TEST2*FIRST*COLUMN NUMBER(4) not null, TEST2*SECOND*COLUMN VARCHAR2(50) not null, TEST2*THIRD*COLUMN DATE, TEST1*FIRST*COLUMN NUMBER(4) not null, constraint PK*TABLE_TEST2 primary key (TEST2_FIRST*COLUMN) using index tablespace TBS_INDEX storage ( initial 100K next 100K ) ) storage ( initial 100K next 100K ) tablespace TBS_DATA; alter table TABLE_TEST2 add constraint TABLE*TEST2__TABLE_TEST1 foreign key (TEST1_FIRST*COLUMN) references TABLE*TEST1 (TEST1_FIRST*COLUMN); ``` My reverse engineering code: ``` ini*set('display*errors', 1); set*include_path(realpath(__DIR_* . '/../doctrine-orm/lib/')); require 'Doctrine/Common/ClassLoader.php'; $classLoader = new \Doctrine\Common\ClassLoader('Doctrine', realpath(*_DIR_* . '/../doctrine-orm/lib/')); $classLoader->register(); $config = new \Doctrine\ORM\Configuration; $cache = new \Doctrine\Common\Cache\ApcCache; $config->setMetadataCacheImpl($cache); $driverImpl = $config->newDefaultAnnotationDriver(realpath(*_DIR_*. '/Infofab/Entities')); $config->setMetadataDriverImpl($driverImpl); $config->setQueryCacheImpl($cache); $config->setProxyDir('Proxies'); $config->setProxyNamespace('Infofab'); $connectionOptions = array( 'dbname' => 'bddmkk', 'user' => 'doctrine', 'password' => 'xxxxxxx', 'host' => 'localhost', 'driver' => 'pdo_oci', 'driverOptions' => array(PDO::ATTR*CASE => PDO::CASE*LOWER) ); $em = \Doctrine\ORM\EntityManager::create($connectionOptions, $config); $sm = $em->getConnection()->getSchemaManager(); $em->getConfiguration()->setMetadataDriverImpl( new \Doctrine\ORM\Mapping\Driver\DatabaseDriver( $em->getConnection()->getSchemaManager() ) ); $cmf = new \Doctrine\ORM\Tools\DisconnectedClassMetadataFactory($em); $metadata = $cmf->getAllMetadata(); $cme = new \Doctrine\ORM\Tools\Export\ClassMetadataExporter(); $exporter = $cme->getExporter('annotation', 'Infofab'); $exporter->setMetadata($metadata); $etg = new \Doctrine\ORM\Tools\EntityGenerator; $exporter->setEntityGenerator($etg); $exporter->export(); ``` If I run this code, I obtain 2 entities: ``` <?php /**** * TableTest1 * * @Table(name="TABLE_TEST1") * @Entity */ class TableTest1 { /**** * @var integer $test1FirstColumn * * @Column(name="TEST1*FIRST*COLUMN", type="integer", nullable=false) * @Id * @GeneratedValue(strategy="SEQUENCE") * @SequenceGenerator(sequenceName="TABLE*TEST1_TEST1_FIRST*COLUMN", allocationSize="10", initialValue="1") */ private $test1FirstColumn; /**** * @var string $test1SecondColumn * * @Column(name="TEST1*SECOND*COLUMN", type="string", length=50, nullable=false) */ private $test1SecondColumn; /**** * @var datetime $test1ThirdColumn * * @Column(name="TEST1*THIRD*COLUMN", type="datetime", nullable=true) */ private $test1ThirdColumn; } ``` and ``` <?php /**** * TableTest2 * * @Table(name="TABLE_TEST2") * @Entity */ class TableTest2 { /**** * @var integer $test2FirstColumn * * @Column(name="TEST2*FIRST*COLUMN", type="integer", nullable=false) * @Id * @GeneratedValue(strategy="SEQUENCE") * @SequenceGenerator(sequenceName="TABLE*TEST2_TEST2_FIRST*COLUMN", allocationSize="10", initialValue="1") */ private $test2FirstColumn; /**** * @var integer $test1FirstColumn * * @Column(name="TEST1*FIRST*COLUMN", type="integer", nullable=false) */ private $test1FirstColumn; /**** * @var string $test2SecondColumn * * @Column(name="TEST2*SECOND*COLUMN", type="string", length=50, nullable=false) */ private $test2SecondColumn; /**** * @var datetime $test2ThirdColumn * * @Column(name="TEST2*THIRD*COLUMN", type="datetime", nullable=true) */ private $test2ThirdColumn; /**** * @var TABLETEST1 * * @OneToOne(targetEntity="TABLETEST1") * @JoinColumns({ * @JoinColumn(name="TEST1*FIRST_COLUMN", referencedColumnName="TEST1_FIRST*COLUMN") * }) */ private $tEST1FIRSTCOLUMN; } ``` As you can see, it declares 2 times the same column: private $test1FirstColumn; and private $tEST1FIRSTCOLUMN;
admin added the Bug label 2026-01-22 12:49:23 +01:00
admin closed this issue 2026-01-22 12:49:23 +01:00
Author
Owner

@doctrinebot commented on GitHub (May 29, 2010):

@doctrinebot commented on GitHub (May 29, 2010): - relates to [DDC-627: Unexpected Duplicate Field Mapping Exception](http://www.doctrine-project.org/jira/browse/DDC-627)
Author
Owner

@doctrinebot commented on GitHub (Jun 13, 2010):

Comment created by @beberlei:

Fixed and scheduled for BETA 3

@doctrinebot commented on GitHub (Jun 13, 2010): Comment created by @beberlei: Fixed and scheduled for BETA 3
Author
Owner

@doctrinebot commented on GitHub (Jun 13, 2010):

Comment created by mikaelkael:

Something is broken with your commit:

Fatal error: Uncaught exception 'Doctrine\ORM\Mapping\MappingException' with message 'No identifier/primary key specified for Entity 'OUTILLAGE*OPERATION*COLLECTE'. Every Entity must have an identifier/primary key.' in /mkk01/doctrine/doctrine-orm/lib/Doctrine/ORM/Mapping/MappingException.php on line 37

Doctrine\ORM\Mapping\MappingException: No identifier/primary key specified for Entity 'OUTILLAGE*OPERATION*COLLECTE'. Every Entity must have an identifier/primary key. in /mkk01/doctrine/doctrine-orm/lib/Doctrine/ORM/Mapping/MappingException.php on line 37

In file 'lib/Doctrine/ORM/Mapping/Driver/DatabaseDriver.php ' (b7db8df7ef) around line 86, the iteration is not complete and it is not able to define the primary key

@doctrinebot commented on GitHub (Jun 13, 2010): Comment created by mikaelkael: Something is broken with your commit: ``` Fatal error: Uncaught exception 'Doctrine\ORM\Mapping\MappingException' with message 'No identifier/primary key specified for Entity 'OUTILLAGE*OPERATION*COLLECTE'. Every Entity must have an identifier/primary key.' in /mkk01/doctrine/doctrine-orm/lib/Doctrine/ORM/Mapping/MappingException.php on line 37 Doctrine\ORM\Mapping\MappingException: No identifier/primary key specified for Entity 'OUTILLAGE*OPERATION*COLLECTE'. Every Entity must have an identifier/primary key. in /mkk01/doctrine/doctrine-orm/lib/Doctrine/ORM/Mapping/MappingException.php on line 37 ``` In file 'lib/Doctrine/ORM/Mapping/Driver/DatabaseDriver.php ' (http://github.com/doctrine/doctrine2/commit/b7db8df7efed4517859be562fd58e6ce4cc6354a) around line 86, the iteration is not complete and it is not able to define the primary key
Author
Owner

@doctrinebot commented on GitHub (Jun 13, 2010):

Comment created by @beberlei:

It seems the detection of many to many tables can cause severe problems. Some internal refactoring has to be done to get this reverse-engineering right.

@doctrinebot commented on GitHub (Jun 13, 2010): Comment created by @beberlei: It seems the detection of many to many tables can cause severe problems. Some internal refactoring has to be done to get this reverse-engineering right.
Author
Owner

@doctrinebot commented on GitHub (Jun 20, 2010):

Comment created by @beberlei:

This should now be finally solved. Many-To-Many tables are detected and supported in reverse engineering now.

@doctrinebot commented on GitHub (Jun 20, 2010): Comment created by @beberlei: This should now be finally solved. Many-To-Many tables are detected and supported in reverse engineering now.
Author
Owner

@doctrinebot commented on GitHub (Jun 20, 2010):

Issue was closed with resolution "Fixed"

@doctrinebot commented on GitHub (Jun 20, 2010): Issue was closed with resolution "Fixed"
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: doctrine/archived-orm#757