JMS serializer - Why are new objects not being instantiated through constructor

mr12086

Why are new entities instantiated with null for all values except the data in the json, why is the entity constructor not setting defaults - putting a die() in the constructor never gets executed.

Update:

Ok so digging into the code, when no managed entity is found, JMSS will use the doctrine instantiator class to create the entity - its sole job, to create entities without calling the constructor. Is there a reason for this? this is inside JMS\Serializer\Construction\UnserializeObjectConstructor


I've configured the object constructor to use the doctrine object constructor written by JMS, but the same issue happens with and without this.

jms_serializer.object_constructor:
    alias: jms_serializer.doctrine_object_constructor
    public: false

Existing entities are updated without trouble, however new entities are missing all constructor set defaults.

Under 'fields' element 0 is existing, element 1 is new.

array (size=3)
  'id' => int 2
  'name' => string 'Categories' (length=10)
  'fields' => 
    array (size=2)
      0 => 
        array (size=7)
          'id' => int 49
          'displayName' => string 'Car Branded' (length=11)
          'type' => string 'checkboxlist' (length=12)
          'required' => boolean false
          'disabled' => boolean false
          'name' => string 'h49' (length=3)
      1 => 
        array (size=3)
          'type' => string 'email' (length=5)
          'name' => string 'field3491' (length=9)
          'displayName' => string 'Email' (length=5)

The entity looks like this after deserializing:

object(stdClass)[2000]
  public '__CLASS__' => string 'AppBundle\Entity\FormElement' (length=28)
  public 'id' => null
  public 'label' => string 'Email' (length=5)
  public 'type' => string 'email' (length=5)
  public 'defaultValue' => null
  public 'required' => null
  public 'mappedField' => null
  public 'garbageCollection' => null
  public 'sortOrder' => null
  public 'disabled' => null
  public 'uuid' => null
  public 'form' => null
  public 'multiOptions' => null
  public 'filters' => null
  public 'submissions' => null

The entity constructor:

public function __construct()
{
    $this->required = false;
    $this->disabled = false;
    $this->garbageCollection = false;
    $this->sortOrder = 0;
    $this->type = 'text';
}

And finally this is how im deserializing:

$serializer = $this->get('jms_serializer');

$entryForm = $serializer->deserialize($json_data, 'AppBundle\Entity\EntryForm', 'json');
mloberg

The issue is the default ObjectConstructor uses Doctrine's Instantiator, which does not call the class' constructor. To solve this, you can create your own ObjectConstructor that just returns a new instance of the class.

Example:

<?php

namespace AppBundle\Serializer;

use JMS\Serializer\Construction\ObjectConstructorInterface;
use JMS\Serializer\DeserializationContext;
use JMS\Serializer\Metadata\ClassMetadata;
use JMS\Serializer\VisitorInterface;

class ObjectConstructor implements ObjectConstructorInterface
{
    /**
     * {@inheritdoc}
     */
    public function construct(
        VisitorInterface $visitor,
        ClassMetadata $metadata,
        $data,
        array $type,
        DeserializationContext $context
    ) {
        $className = $metadata->name;

        return new $className();
    }
}

If you're using the bundle, just set jms_serializer.unserialize_object_constructor.class parameter to that new class. Otherwise in your builder, use the class as your object constructor.

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related

Add objects in an ArrayList through constructor

Why List can remove a new object that is not instantiated

Can new objects be instantiated without the = new Obj ()?

How to handle recursive objects with JMS Serializer

Data declaration with no data constructor. Can it be instantiated? Why does it compile?

Why are classes mostly instantiated through functions?

Why should LiveData objects in ViewModel be instantiated during declaration?

Creating multiple objects and passing parameters through constructor

new property can not be instantiated in derived class constructor

Why is my objects key, value pair being overridden instead of creating a new key, value pair?

JMS Serializer deserialize nested objects

Why is the move constructor not being called here?

How to loop through a list of the instantiated objects in Python classes?

Why is QAudioRecorder not recording through the constructor?

Why is constructor being invoked?

Initialising/Creating Objects through a constructor

Why constructor is being called twice

Adding new objects to an ArrayList in constructor

Why are no-arg constructors subject to being instantiated in an invalid state?

XML deserialization with JMS Serializer

Objects not being added by constructor to a list of all objects

Why is my constructor being called when I assign two objects of that class?

Why is the move constructor being called?

JMS Serializer deserialize ArrayCollection of Objects

JMS Serializer does not apply formatting to newly created objects

JS: How can I add items to an new Objects array, instantiated from a constructor?

Why are the objects instantiated differently in these BLOC events?

Creating a vector of all instances of a class when objects are being instantiated in a loop?

If std::vector reallocates objects to new memory by using move constructor then why does it have to call the destructor on the original objects?