Dynamic Table/Entity names in Doctrine 2

2019-04-08 12:27发布

问题:

I am hoping someone can shed some light on what is going on with my code.

I need to have an entity that represents a generic table as a model for tables with X id suffix. For example, I have an entity: CustomerX The tables I need to query are cusotmer_1, customer_2, customer_3...etc..

I am currently using:

class CustomerX {
/**
 * CustomerX
 *
 * @Table(name="customer_")
 * @Entity
 */


//..... properties and setters/getters....

private $_tableName = null;

public function getTableName() {
    return $this->_tableName;
}

public function setTableName($tableName) {
    $this->_tableName = $tableName;
    return $this;
}

public function loadClassMetadata(LoadClassMetadataEventArgs $eventArgs)
{
    $classMetadata = $eventArgs->getClassMetadata();

    $table = $classMetadata->table;
    $table['name'] = 'customer_'.$this->getTableName();
    $classMetadata->setPrimaryTable($table);
}


public static function getCustomerRecords($CustomerId) {
    $em = \Helper_Doctrine::em();

    $custTable = new \ME\CustomerX();
    $custTable->setTableName($CustomerId);
    $evm = $em->getEventManager();
    $evm->addEventListener(\Doctrine\ORM\Events::loadClassMetadata, $custTable);

    //get the customer info
    $query = $em->createQuery(
        'SELECT w
         FROM \ME\CustomerX w
         WHERE w.customerId = :CustId';
    $query->setParameter('CustId', $CustomerId);
    $custParams = $query->getResult();

    $evm->removeEventListener(\Doctrine\ORM\Events::loadClassMetadata, $custTable);
    $em->flush();

    return $custParams;
}

}

So the issue is, i can get this to set correctly the first time I run through getting a customer, but then the second time, the sql generated by doctrine ends up using the first table I created.

So if i run: CustomerX::getCustomerRecords('123') first, the sql that gets executed and when I run CustomerX::getCustomerRecords('987') still is using 'customer_123'.

I must be doing something wrong. If anyone has any suggestions on how to correctly remove or reset the table name to something new, that would be great.

Thanks.

I initially used this as reference. Programmatically modify table's schema name in Doctrine2?

回答1:

Question is old, but it can be helpful for someone.

If loadClassMetada called each time then it seems that issue in your code. But, I suppose, that metadata is cached by doctrine. In that case you can change it directly, please look following code snippet, it should work:

<?php
class FooController extends Controller {
  function fooAction() {
    $em = $this->getDoctrine()->getEntityManager();
    $cm = $em->getClassMetadata('FooBundle:FooEntity');
    $cm->setTableName('special_table_name');
    $repo = $em->getRepository('FooBundle:FooEntity');
    $entities = $repo->createQueryBuilder('f')
            ->setMaxResults(1)
            ->orderBy('f.id', 'desc')
            ->getQuery()
            ->getResult();
    return new Response('');
  }
}