mirror of
https://github.com/doctrine/orm.git
synced 2026-03-24 06:52:09 +01:00
Check if Data Type implementes Stringable interface for Primary keys #6946
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 @michnovka on GitHub (Mar 8, 2022).
Feature Request
I came across this issue recently
Summary
I think that if field has defined type in PHP Entity, then Doctrine should check whether this type implements Stringable interface (has __toString() method). If not, an error should be thrown, as UnitOfWork cannot keep track of changes and whole ORM is thus broken.
@derrabus commented on GitHub (Mar 9, 2022):
I wonder if we should rather leverage the type system here. After all, it's the database representation of the ID and the type system could get us that representation.
@michnovka commented on GitHub (Mar 9, 2022):
@derrabus yes, I agree. We could add
Type::convertToPHPString(): stringmethod orconvertToPHPStringable(): \StringableDBAL would then check if
#[ORM\Id]is set on column whether this method is implemented and if not, it would throw an error.A default
Typeimplementation could be:This would allow for already
Stringabletypes to work without any further modification or method overloading.@michnovka commented on GitHub (Mar 9, 2022):
Since the above would work only for PHP8, we can do instead
@michnovka commented on GitHub (Mar 9, 2022):
@derrabus isnt this more for dbal than orm? as we need to edit
Doctrine\DBAL\Types\Type@derrabus commented on GitHub (Mar 9, 2022):
Well, the main problem is that naive string cast inside
UnitOfWork. That's an ORM problem. And no, I don't think we have to change theTypeclass. ItsconvertToDatabaseValue()method should be pretty much what we need.@michnovka commented on GitHub (Apr 2, 2022):
@derrabus I ran into similar issue again with https://github.com/doctrine/orm/pull/9624
so given your suggestion, why not use the convertToDatabaseValue() function to flatten IDs?
@beberlei commented on GitHub (Apr 2, 2022):
There are some historical reasons why this was not done before, bugs of this kind with DateTime instances have been discussed on this tracker many times.
@beberlei commented on GitHub (Apr 2, 2022):
Onw reasone we dont convert all fields via types to db representation before computing key representation is performance. As this operation is needed many times in each UoW <=> entity interaction .
@michnovka commented on GitHub (Apr 2, 2022):
@beberlei so is the issue with IdentifierFlattener.php ? The performance point you make is true, but at the same time we already cast all value types to string. I do not believe there would be a huge overhead.
At this point it is impossible to e.g. use BackedEnums as IDs. There is no __toString() allowed in BackedEnums. For other custom types, this method can be overloaded and it will work.
@michnovka commented on GitHub (Apr 13, 2022):
After working a bit more on similar issue, I still think that the proper way is to extend DBAL
Then let IdentifierFlattener check whether the ID value is stringable. If (and only if) not, fetch the underlying type and call
convertToPHPString()method.This would eliminate this overhead, as it would be called only where necessary (and where currently it would not work and throw exception anyways). Thus the additional work would be done only for case which is currently unsupported. WDYT @beberlei ?