Bug(?) when resetting IdGenerator(Type) #5084

Closed
opened 2026-01-22 14:57:55 +01:00 by admin · 5 comments
Owner

Originally created by @ghost on GitHub (Apr 8, 2016).

Hi,

We need to have some fixture entities with set ids and therefore we do the following in the specified order:

  • save old idGenerator and idGeneratorType
  • change idGenerator and idGeneratorType to to AssignedGenerator and ClassMetadata::GENERATOR_TYPE_NONE, respectively (see here why)
  • execute fixtures
  • restore idGenerator and idGeneratorType to the old saved values (we want the default behavior from here on)
  • remaing test code gets executed

And here is the problem: When test code is storing an entity, it now must assign a id (which is only wanted for fixtures), otherwise the following error gets thrown:

An exception occurred while executing 'INSERT INTO foos (id, firstname, lastname) VALUES (?, ?, ?)' with params ["yo", "ya"]: SQLSTATE[HY000]: General error: 20 datatype mismatch

It appears that id and it's value placeholder are still there, although the idGenerator and type have been reset and the params have adapted. Without executing the fixtures, the code works without any problems.

To help you reproduce this, I've setup a repo which reproduces exactly this error: https://github.com/whatda/bug

Just do a composer install and try it with phpunit. There's a var_dump and die in the single test, which currently isn't reached because of the error I pointed out.

Any help is really appreciated. Thanks for reading.

Originally created by @ghost on GitHub (Apr 8, 2016). Hi, We need to have some fixture entities with set ids and therefore we do the following in the specified order: - save old idGenerator and idGeneratorType - change idGenerator and idGeneratorType to to `AssignedGenerator` and `ClassMetadata::GENERATOR_TYPE_NONE`, respectively (see [here](http://stackoverflow.com/questions/5301285/explicitly-set-id-with-doctrine-when-using-auto-strategy) why) - execute fixtures - restore idGenerator and idGeneratorType to the old saved values (we want the default behavior from here on) - remaing test code gets executed And here is the problem: When test code is storing an entity, it now must assign a id (which is only wanted for fixtures), otherwise the following error gets thrown: `An exception occurred while executing 'INSERT INTO foos (id, firstname, lastname) VALUES (?, ?, ?)' with params ["yo", "ya"]: SQLSTATE[HY000]: General error: 20 datatype mismatch` It appears that id and it's value placeholder are still there, although the idGenerator and type have been reset and the params have adapted. Without executing the fixtures, the code works without any problems. To help you reproduce this, I've setup a repo which reproduces exactly this error: https://github.com/whatda/bug Just do a composer install and try it with phpunit. There's a `var_dump` and `die` in the single test, which currently isn't reached because of the error I pointed out. Any help is really appreciated. Thanks for reading.
admin added the BugImprovement labels 2026-01-22 14:57:55 +01:00
admin closed this issue 2026-01-22 14:57:56 +01:00
Author
Owner

@Majkl578 commented on GitHub (Sep 11, 2017):

This will be related to how mapping is built. ID generators are completed in metadata factory and are not intended directly for changes at runtime. You would have to manually change the idGenerator instance of the class metadata, by calling i.e. $classMetadata->setIdGenerator(new \Doctrine\ORM\Id\AssignedGenerator()).
The code around generators has been heavily rewritten in develop (3.0), but this is still to be solved afaik.

@Majkl578 commented on GitHub (Sep 11, 2017): This will be related to how mapping is built. ID generators are [completed in metadata factory](https://github.com/doctrine/doctrine2/blob/v2.5.10/lib/Doctrine/ORM/Mapping/ClassMetadataFactory.php#L612) and are not intended directly for changes at runtime. You would have to manually change the idGenerator instance of the class metadata, by calling i.e. `$classMetadata->setIdGenerator(new \Doctrine\ORM\Id\AssignedGenerator())`. The code around generators has been heavily rewritten in develop (3.0), but this is still to be solved afaik.
Author
Owner

@b4cedev commented on GitHub (Oct 19, 2017):

I'm having exactly the same problem.
Changing idGenerator and generatorType has the desired effect so the fixtures can create entities using specified ids.
However, restoring idGenerator and generatorType (by using the setters) to the previously saved values doesn't restore the previous behaviour, but triggers the error mentioned by @whatda.
As the tests are run against an in-memory sqlite db i can't simply load fixtures and run tests in separate processes.
Would be happy to get any hint what's going wrong there before 3.0 ;)

@b4cedev commented on GitHub (Oct 19, 2017): I'm having exactly the same problem. Changing idGenerator and generatorType has the desired effect so the fixtures can create entities using specified ids. However, restoring idGenerator and generatorType (by using the setters) to the previously saved values doesn't restore the previous behaviour, but triggers the error mentioned by @whatda. As the tests are run against an in-memory sqlite db i can't simply load fixtures and run tests in separate processes. Would be happy to get any hint what's going wrong there before 3.0 ;)
Author
Owner

@arnegroskurth commented on GitHub (Apr 11, 2019):

I'm having the exact same problem. The root cause seems to be this line: ebb53acda9/lib/Doctrine/ORM/Persisters/Entity/BasicEntityPersister.php (L1469)

The insert-statement SQL is cached by the BasicEntityPersister when the first insert is executed - in this case WITH the id field. After restoring the id generator setting this cached statement is not reset as well which causes the cached statement to be executed without the id in the parameters which then causes the mismatch.

@arnegroskurth commented on GitHub (Apr 11, 2019): I'm having the exact same problem. The root cause seems to be this line: https://github.com/doctrine/orm/blob/ebb53acda96e304a6f91d4a5a2d76378a4e1d210/lib/Doctrine/ORM/Persisters/Entity/BasicEntityPersister.php#L1469 The insert-statement SQL is cached by the BasicEntityPersister when the first insert is executed - in this case WITH the id field. After restoring the id generator setting this cached statement is not reset as well which causes the cached statement to be executed without the id in the parameters which then causes the mismatch.
Author
Owner

@lcobucci commented on GitHub (Nov 15, 2019):

As @guilhermeblanco said in https://github.com/doctrine/orm/pull/7677#issuecomment-521346887 this has been designed to not be modified in runtime. @guilhermeblanco this should then be closed as well, right?

@lcobucci commented on GitHub (Nov 15, 2019): As @guilhermeblanco said in https://github.com/doctrine/orm/pull/7677#issuecomment-521346887 this has been designed to not be modified in runtime. @guilhermeblanco this should then be closed as well, right?
Author
Owner

@derrabus commented on GitHub (May 11, 2022):

I'm closing this issue because it hasn't seen progress for several years.

@derrabus commented on GitHub (May 11, 2022): I'm closing this issue because it hasn't seen progress for several years.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: doctrine/archived-orm#5084