Multiple tables on single entity (unique schema) #5386

Closed
opened 2026-01-22 15:06:07 +01:00 by admin · 2 comments
Owner

Originally created by @PillowPillow on GitHub (Jan 16, 2017).

Originally assigned to: @Ocramius on GitHub.

Hello. We have an issue with our current doctrine setup.
We would like to map a unique entity to multiple generated tables.
I know that's not a standard usage but our constraint necessitate some optimizations and we need to split our tables by account.

We tried to update the repository table name by calling setPrimaryTable on the classMetadata property before each queries. However, it seems that we can't update the table after the first execution.

Working example :

<?php
	//...
	$em = $this->getDoctrine()->getManager();
	$productM = $em->getRepository('DataBundle:Product');
	$classMetaData = $em->getClassMetadata('DataBundle:Product');
	
	
	$classMetaData->setPrimaryTable(['name' => 'product_copy']);
	$productM->findAll(); // select * from product_copy;

Problematic case :

<?php
	//...
	$em = $this->getDoctrine()->getManager();
	$productM = $em->getRepository('DataBundle:Product');
	$classMetaData = $em->getClassMetadata('DataBundle:Product');
	
	$productM->findAll(); // select * from product;
	
	$classMetaData->setPrimaryTable(['name' => 'product_copy']);
	$productM->findAll(); // select * from product;

Is there a proper solution to handle this case to be compliant with the doctrine philosophy? Is it at least possible?

We saw an other "solution" digging into the Gidmo code, using the AST walkers but that can only handle the select cases, not the other CRUD operations.

<?php
	class FromWalker extends SqlWalker {
	
		public function walkRangeVariableDeclaration($rangeVariableDeclaration)
		{
			$sql = parent::walkRangeVariableDeclaration($rangeVariableDeclaration);
			// replace the table name by a custom one
			return $sql;
		}
		
	}

Thanks for your attention.
Best regards

Nicolas

Originally created by @PillowPillow on GitHub (Jan 16, 2017). Originally assigned to: @Ocramius on GitHub. Hello. We have an issue with our current doctrine setup. We would like to map a unique entity to multiple generated tables. I know that's not a standard usage but our constraint necessitate some optimizations and we need to split our tables by account. We tried to update the repository table name by calling *setPrimaryTable* on the classMetadata property before each queries. However, it seems that we can't update the table after the first execution. Working example : ````php <?php //... $em = $this->getDoctrine()->getManager(); $productM = $em->getRepository('DataBundle:Product'); $classMetaData = $em->getClassMetadata('DataBundle:Product'); $classMetaData->setPrimaryTable(['name' => 'product_copy']); $productM->findAll(); // select * from product_copy; ```` Problematic case : ````php <?php //... $em = $this->getDoctrine()->getManager(); $productM = $em->getRepository('DataBundle:Product'); $classMetaData = $em->getClassMetadata('DataBundle:Product'); $productM->findAll(); // select * from product; $classMetaData->setPrimaryTable(['name' => 'product_copy']); $productM->findAll(); // select * from product; ```` Is there a proper solution to handle this case to be compliant with the doctrine philosophy? Is it at least possible? We saw an other "solution" digging into the Gidmo code, using the AST walkers but that can only handle the select cases, not the other CRUD operations. ````php <?php class FromWalker extends SqlWalker { public function walkRangeVariableDeclaration($rangeVariableDeclaration) { $sql = parent::walkRangeVariableDeclaration($rangeVariableDeclaration); // replace the table name by a custom one return $sql; } } ```` Thanks for your attention. Best regards Nicolas
admin added the ImprovementCan't Fix labels 2026-01-22 15:06:07 +01:00
admin closed this issue 2026-01-22 15:06:07 +01:00
Author
Owner

@Ocramius commented on GitHub (Jan 17, 2017):

Modifying metadata at runtime is simply not supported, as the metadata details may be cached within the various ORM components.

You may, though, create multiple metadata instances, each for a different class/interface, and then make the reflection details point at a single class.

This will still fail to correctly work with managed instances though.

Closing as can't fix.

@Ocramius commented on GitHub (Jan 17, 2017): Modifying metadata at runtime is simply not supported, as the metadata details may be cached within the various ORM components. You may, though, create multiple metadata instances, each for a different class/interface, and then make the reflection details point at a single class. This will still fail to correctly work with managed instances though. Closing as `can't fix`.
Author
Owner

@bululu commented on GitHub (May 14, 2018):

Hello,
I had the same problem and i was able to workaround it with $em->clear();
to clear the cache so the table would refresh

//...
$em = $this->getDoctrine()->getManager();
$productM = $em->getRepository('DataBundle:Product');
$classMetaData = $em->getClassMetadata('DataBundle:Product');

$productM->findAll(); // select * from product;

    $em->clear();

$classMetaData->setPrimaryTable(['name' => 'product_copy']);
$productM->findAll(); // select * from product;
@bululu commented on GitHub (May 14, 2018): Hello, I had the same problem and i was able to workaround it with $em->clear(); to clear the cache so the table would refresh //... $em = $this->getDoctrine()->getManager(); $productM = $em->getRepository('DataBundle:Product'); $classMetaData = $em->getClassMetadata('DataBundle:Product'); $productM->findAll(); // select * from product; $em->clear(); $classMetaData->setPrimaryTable(['name' => 'product_copy']); $productM->findAll(); // select * from product;
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: doctrine/archived-orm#5386