0

JMSSerializer comes with a Doctrine Object Constructor that does its job, but imagine an Entity with two properties forming a primary key:

UserBase
    prop annotated with @ORM\Id and @Serializer\Groups({"1"})
  - username
    prop annotated with @ORM\Id and @Serializer\Groups({"2"})
  - email

User extends UserBase
  - other props here, no Id defined.

one property key is excluded by using group=1 while deserializing. The client potentially still sends both email and username. email should not be considered though.

Unfortunately, if you pass the two properties in the body, DoctrineObjectConstructor does not check if something is excluded by deserialization, so it tries to load the Entity from the DB, according to the two values:

    foreach ($classMetadata->getIdentifierFieldNames() as $name) {
        if ( ! array_key_exists($name, $data)) {
            return $this->fallbackConstructor->construct($visitor, $metadata, $data, $type, $context);
        }

        $identifierList[$name] = $data[$name];
    }

What I would like to do is taking into account my annotated groups, so as to use the fallbackConstructor in case some property forming the identifier is missing.

As a starter this is a good point: I created my own service, by passing along the annotationDriver. Then, if the property forming the identifier is not associated with the actual group:

$classMetadata = $this->annotationDriver->loadMetadataForClass($metadata->reflection);
$classMetadata->properties //here groups are listed for each property

I can fall back to the fallbackConstructor, as if I had not passed that property in the body

...not so fast! My Entity User extends a UserBase where all my identifier are, so I should take into account hierarchy, possibly in a generic way.

Any hint?

Bertuz
  • 2,390
  • 3
  • 25
  • 50

1 Answers1

0

Alright, JMSSerializer's Object Constructor does not consider serialization groups when determing identifiers. Hence, if you include all the IDs in your object, whether they are part of the actual context group or not, they will be counted in.

I created an alternative version of the Object in order to fix this misbehavior (at least for me). Hope it helps

Bertuz
  • 2,390
  • 3
  • 25
  • 50