Closed videni closed 4 years ago
I'm not 100% sure this is the cause of your issue. Indeed this false === $generator->isPostInsertGenerator()
is here to ensure we don't disable unnecessarily the generator over and over again. So at first glance, I see two possibilities:
App\Bundle\AdvertisementBundle\Entity\AdAsset
has an ID assigned causing the generator to be wrongly disabled (generators are on a class basis, not entity basis, since Doctrine's Metadata are for the whole class)If it's none of those, I would need a reproducer to be able to debug this and look deeper into it
Hi @theofidry I am having the same issue.
My entity is using the Doctrine\ORM\Id\IdentityGenerator
. I used to load a set of base fixtures to be shared for all the test scenario fixtures. I load them in different LoaderInterface::load
callings but under the same execution.
To do not load the base fixtures over and over, they are persisted using a Doctrine\Common\DataFixtures\ProxyReferenceRepository
class.
Then just right before the rest of test scenario fixtures are going to be loaded, I fetch the base fixtures from the proxy reference repository and I add them as part of the initial objects array.
if (!$isBaseFixtureFile) {
// ...
$objects = array_merge($objects, $proxyRepository->getReferences());
}
// Decorated ObjectManagerPersister
$this->delegate->load($fixturesFiles, $parameters, $objects, $purgeMode);
So all the base objects from the proxy repository were persisted and have an ID. When ObjectManagerPersister
iterates over them, it changes the metadata information.
$metadata->usesIdGenerator() && false === empty($metadata->getIdentifierValues($object))
After the doctrine object manager persists the base objects, the next condition is never met because my generator isPostInsertGenerator
returns true.
null !== $generator && false === $generator->isPostInsertGenerator())
That will be OK for other base fixtures with same class, but if I have fixtures with the same class in the second load calling, then as the metadata wasn't restored, the new objects will raise an ORMException because Doctrine cannot generate an ID for them (generator type none was set)
This was working well for v1.0.1 when it was only comparing null !== $generator
What would it be the best approach?
I think I can downgrade to v1.0.1, but I would like to have the new fixes from v1.1.2
Thanks!!!
Maybe an alternative approach to your problem @ixarlie would be to:
You can try that approach locally, if that solves your problem I'll be more than happy to accept a patch for it although I admit I would really really appreciate a test to reproduce your issue in order to avoid regressions in the future: it's a very tricky part, so any additional test to capture problematic edge cases are greatly appreciated
Restor not work without reset \Doctrine\ORM\Persisters\Entity\BasicEntityPersister->insertSql
to null
.
The reason is that \Doctrine\ORM\Persisters\Entity\BasicEntityPersister save generate INSERT request and does not regenerate it if the id generator has changed.
Hack solution working for me. Usage example:
class A{
public function __construct(ChangeIdentityGeneratorHelper $changeIdentityGeneratorHelper)
{
// Create prepaire user
$entity = new User();
$entity->setId(1);
// .....
$changeIdentityGeneratorHelper->changeIdentity(
User::class,
ClassMetadata::GENERATOR_TYPE_NONE,
new AssignedGenerator()
);
// persist and flush entities
$changeIdentityGeneratorHelper->restoreIdentity(User::class);
// Create not prepaire user
$entity = new User();
// .....
// persist and flush entities
}
}
@uginroot can you out https://github.com/theofidry/AliceDataFixtures/pull/135?
I wandered here because Google did not find a solution. I left my decision here to help those who have the same problem. I do not use theofidry / AliceDataFixtures, I just encountered the same problem in my project, and decided to leave a solution to a similar problem here. This problem should be solved by the doctrine developers.
I don't think it's a problem on Doctrine side: we are changing the class metadata, that's our problem... #135 is precisely a fix for that
Tomorrow I will add a method clearInsertSqlQueryCache
and if it is accepted then the problem can be solved without hacks.
Hopefully fixed by #135
in my case was the number of parameters, passed through the insert statement,in a form with re-captcha,he insert an hidden input,with the name without value and when pass the array to insert statement this failure happen
Voici mon code
function ajouter($nom,$prix, $image,$desc) { if(require("connexion.php")) { $req=$access->prepare("INSERT INTO Products(nom, prix, image, description) VALUES ('$nom',$prix,'$image','$desc')"); $req->execute(array($nom, $prix, $image, $desc));
$req->closeCursor();
Voilà l'erreur , aider moi
Warning: PDOStatement::execute(): SQLSTATE[HY093]: Invalid parameter number: number of bound variables does not match number of tokens in /opt/lampp/htdocs/shop/config/commandes.php on line 28
it seems there is bug in this bundle which costs me a whole day. when doctrine tries to insert
adAsset2
into database , it gives the erroras you can see below, the AdAsset is the same Area entity, the later has no problem. why did this happen? I found out that the original id generator can't alway be restored. the exception will disappear if remove
false === $generator->isPostInsertGenerator()
.theofidry/alice-data-fixtures/src/Bridge/Doctrine/Persister/ObjectManagerPersister.php
fixture.yml
call stack