mirror of
https://github.com/doctrine/orm.git
synced 2026-03-24 06:52:09 +01:00
Bug if you want to have an AUTO_INCREMENT id and an UUID #5963
Reference in New Issue
Block a user
Delete Branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Originally created by @Chemaclass on GitHub (May 7, 2018).
Originally assigned to: @Ocramius on GitHub.
Scenario:
I want to have an AUTO_INCREMENT
idfrom my DB layer, and also have ahashas Uuid.If you have your entity like this:
When you try to persist a new entity:
Problem:
You will get an error saying:
I was wondering why this was happening so I went deeper into Doctrine, and inside
UnitOfWord::persistNew($class, $entity)I found something interesting:$idGen = $class->idGenerator; [line: 895]is aUuidGenerator!?But shoulnd't it be the generator for the
idproperty the@ORM\Id | @ORM\GeneratedValue(strategy="IDENTITY")auto increment by default? Why it seems to be overrite it by the newRamsey Uuid Generator?After a little research I came with the conclusion that Doctrine annotations -in order to determine the idGenerator- it loads by order which is the idGenerator for the entity. Which means the last one (annotation) override the previous one.
I came with this solution:
Conclusion: the solution was just moving as last annotation the
idproperty from the entity which it is actually the real id (as AUTO_INCREMENT int from the DB) and still have theUuidfromRamsey\Uuid\Uuid.I think we should avoid this ordering problem in our entities files and takes the idGenerator from the property which has
@ORM\Id.@kalifg commented on GitHub (Oct 25, 2018):
There's no place in the Doctrine code that will use an
IdentityGeneratorfor a non-identity field. Uses ofIdentityGenerator::generate(): here, here and here; all deal with setting the identity fields.I agree that if this is intentional, then it's a bug that the metadata loader still looks for the generator even if the field is not part of the identity.
This isn't UUID-specific, it goes for anything field type that you might want to generate automatically. The way things currently work, if you want to automate the generation of a non-identity field then you will need to use an event listener of some sort (I'd start with
prePersist)@kalifg commented on GitHub (Oct 25, 2018):
I'll also point out that the XML, Yaml and Database drivers do seem to isolate the setting of custom generators to id elements.
@kalifg commented on GitHub (Oct 25, 2018):
My code references were for 2.5 — master seems to have some heavy changes in it, but I believe it still has the same issue here
@Majkl578 commented on GitHub (Oct 25, 2018):
GeneratedValue currently only works for identifier fields on non-composite identified entities.
@metalmini commented on GitHub (Mar 8, 2019):
So, is this by design or a bug?
@Majkl578 commented on GitHub (Mar 8, 2019):
This is currently by design but it could become supported in ORM 3.0.
Note that in ORM 3.0 the UUID generator strategy will be removed, please use constructor injection for passing entity (uu)IDs.
@damianprzygodzki commented on GitHub (Apr 4, 2019):
And what if you want UUID as Your IDENTITY and have internal AUTO GENERATED int in entity? It cries:
@Majkl578 commented on GitHub (Apr 4, 2019):
I'd recommend using ramsey/uuid-doctrine:
It also provides UuidGenerator but I'd advise against that.
@damianprzygodzki commented on GitHub (Apr 4, 2019):
@Majkl578
But it won't work.
@Ocramius commented on GitHub (Apr 4, 2019):
Only identifiers can have
@GeneratedValue@Ocramius commented on GitHub (Apr 4, 2019):
Closing here. As mentioned above:
Please open a new issue with a schema validator patch (preventing usage of
@GeneratedValueon non-identifiers or composite identifiers), if needed.@Chemaclass commented on GitHub (Apr 4, 2019):
That's true, but actually, an AUTO_INCREMENT can be applied only to one key in a table, but not necessarily the PK.
Consider this example:
So, technically
Only identifiers can have @GeneratedValueis only for Doctrine by design, because at a lower level(SQL) we could say something like:Any Key can have a @GeneratedValue, but only one per Entity/Table.In such case, this would allow this logic:
@Ocramius commented on GitHub (Apr 4, 2019):
Yes, it can, but the ORM will not re-fetch data from the underlying layer after
INSERT/UPDATE, so this won't ever work.Same applies for:
@vince83110 commented on GitHub (Dec 27, 2021):
Having the same issue, I just want to have the oppositte : my IDs are Uuid, and I want a field "code" with an auto-increment.
I changed the order of fields in my Entity as mentioned, but still have the same error:
I generate the UUid in the constructor, so no need of GeneratedValue strategy.
Any solution ? Thanks
@derrabus commented on GitHub (Dec 27, 2021):
Please use GitHub discussions for support requests. Only few people monitor comments on issues that have been closed for years.
@ghandhikus commented on GitHub (Oct 17, 2023):
This bug still persists in newer versions of Symfony, it should be fixed ngl. Sequence generation is a must even if the primary key is a UUID and you want to generate an ID on top of that.
@ghandhikus commented on GitHub (Oct 17, 2023):
Workaround
For anyone wondering how to solve this, use something similar, but write your own code for sequence generation in the migration, make sure you default it in the migration itself too.
Edit: if you are using schema:update for your unit testing database then remove default or consider using slower migrations for it