-
-
Notifications
You must be signed in to change notification settings - Fork 9.6k
[Serializer] Unable to deserialize into existing Doctrine entities #15627
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
The actual class is located in doctrine. See: https://github.com/symfony/security-acl/pull/3/files#diff-f95db4a0923d2b083e7c0d2d111c722eR46 |
@iltar the same code is also present in Symfony: https://github.com/symfony/symfony/blob/2.8/src/Symfony/Component/Security/Core/Util/ClassUtils.php#L55-L63 Btw we also have the same code in API Platform for the same reason (Doctrine): https://github.com/dunglas/DunglasApiBundle/blob/dcfee7f57e0fba8d85db214f2993bcf37a910209/Util/ClassInfoTrait.php#L30-L33 I'm not fond of adding |
@dunglas I'm actually moving it from there to the ACL, because it's not used anywhere in the security component but the ACL. My idea was to create an injectable class that arranges this. The doctrine bridge can hook in on that and create a custom implementation that can resolve proxy names to entity names, which would make it re-usable here. Once in the doctrine bridge, the doctrine bundle can add a "resolver" of some sort to the resolver service ( |
If the proxy class exists, then you should be actually able to deserialize back into into a proxy. Why do you want a cast? |
@dunglas I actually found this issue while using DunglasApiBundle. ItemNormalizer successfully overrides the class name to deserialize when it finds the object via I think you got rid of the controller after beta 3 so I'm not sure if this still applies, but that's how I stumbled across this. @Ocramius The idea is to deserialize back in to the proxy. The serializer does not handle this correctly because the proxy class name does not match the expected class name, and thus it tries to create a new object. The serializer is unaware that a proxy exists. |
It should stay like that. Is there a test case for this? Basically: $this->assertSame(
get_class($proxy),
get_class($serializer->unserialize($serializer->serialize($proxy)))
); |
Probably that simply changing https://github.com/symfony/symfony/blob/master/src/Symfony/Component/Serializer/Normalizer/AbstractNormalizer.php#L250 by @bwegrzyn can you provide a snippet we can use to reproduce the problem (ideally a failing unit test)? |
I do not have a failing test ready, but the following will fail provided that $manager = $this->get('doctrine')->getManager();
$serializer = $this->get('serializer');
// `User` entity is loaded from repository without eagerly loading relations
$repository = $manager->getRepository('MyBundle:User');
// $entity is instance of Proxies\__CG__\MyBundle\User
$entity = $repository->find(1);
// Deserialize json in to existing $entity
$deserializedEntity = $serializer->deserialize(
'{"name":"bwegrzyn"}',
'MyBundle\\Entity\\User',
'json',
['object_to_populate' => $entity]
);
// Observe that $deserializedEntity !== $entity and is missing properties that were loaded from the database |
…unglas) This PR was merged into the 2.7 branch. Discussion ---------- [Serializer] Allow to use proxies in object_to_populate | Q | A | ------------- | --- | Bug fix? | yes | New feature? | no | BC breaks? | no | Deprecations? | no | Tests pass? | yes | Fixed tickets | #15627, api-platform/core#381 | License | MIT | Doc PR | n/a Allows to populate a proxy (or any class having the given type). Commits ------- b16b5b9 [Serializer] Allow to use proxies in object_to_populate
Doctrine entities are sometimes wrapped in Proxy objects, and the
instantiateObject
method does not handle them transparently.For example, an entity
MyBundle\Entity\User
might have a class name ofProxies\__CG__\MyBundle\Entity\User
. When this occurs, theinstantiateObject
method does not detect that it is in fact the same entity, and attempts to create a new one.The Security component uses
ClassUtils::getRealClass()
to get around this issue.I believe the issue is with the following line of code:
https://github.com/symfony/symfony/blob/master/src/Symfony/Component/Serializer/Normalizer/AbstractNormalizer.php#L250
The text was updated successfully, but these errors were encountered: