how to update symfony2/doctrine entity from a @Groups inclusion policy JMSSerializer deserialized entity

后端 未结 3 1219
清酒与你
清酒与你 2020-12-09 05:35

I\'m trying to update symfony2/doctrine entities using JMSSerializer with an @ExclusionPolicy:None @Groups Inclusion Policy.

 * @Serializer\\ExclusionPolicy(         


        
相关标签:
3条回答
  • 2020-12-09 06:04

    To use JMS deserializer for MongoDB documents and ORM entities you can use

    jms_serializer.doctrine_mongodb_object_constructor:
        class:        %jms_serializer.doctrine_object_constructor.class%
        public:       false
        arguments:    ["@doctrine_mongodb", "@jms_serializer.unserialize_object_constructor"]
    
    jms_serializer.doctrine_object_constructor:
        class:        %jms_serializer.doctrine_object_constructor.class%
        public:       false
        arguments:    ["@doctrine", "@jms_serializer.doctrine_mongodb_object_constructor"]
    
    jms_serializer.object_constructor:
        alias: jms_serializer.doctrine_object_constructor
        public: false
    

    As you see in jms_serializer.doctrine_object_constructor second argument (fallbackConstructor) is jms_serializer.doctrine_mongodb_object_constructor it means that if your object isn't entity then jms will try to use fallbackConstructor and if your deserialised object isn't Document either then will be used default unserialize_object_constructor

    if you deserialize entity

    $em->persist($foo);
    $em->flush();
    

    if document

    $dm->persist($foo);
    $dm->flush();
    
    0 讨论(0)
  • 2020-12-09 06:15

    I found the answer.

    $serializer is a service created by the symfony2 integration bundle JMSSerializerBundle.

    The default service is jms_serializer.serializer initializes the JMSSerializer with the default Object Constructor UnserializeObjectConstructor and for doctrine I needed to deserialize with the DoctrineObjectConstructor.

    because I only use JMSSerializer in the project for serialize/deserialize of doctrine entities, I overwrote JMSSerializerBundle's jms_serializer.object_constructor with the alias of the proper object constructor service.

    <service id="jms_serializer.object_constructor" alias="jms_serializer.doctrine_object_constructor" public="false"/>
    

    Is there a better way to configure what object constructor the serializer uses?

    I also added the proper context to deserialize:

    $serializer->deserialize($jsonFoo,'Foo','json', DeserializationContext::create()->setGroups(array('flag')));
    
    result:
    Foo (id:1, name:'bar', flagged:true ,created_by:123)
    

    Using the doctrine object constructor, it figures out that I want to find the object and only apply updates to fields provided in $jsonFoo (and the flag group). This totally eliminates the need for doctrines entity manager merge and I can just persist the object properly.

    $em->persist($foo);
    $em->flush();
    
    0 讨论(0)
  • 2020-12-09 06:20

    in addition to @Heyflynn's answer (thanks!), I needed this to work with doctrine_mongodb, so I modified my services.yml as follows:

    services:
        jms_serializer.doctrine_object_constructor:
            class:        %jms_serializer.doctrine_object_constructor.class%
            public:       false
            arguments:    ["@doctrine_mongodb", "@jms_serializer.unserialize_object_constructor"]
    
        jms_serializer.object_constructor:
            alias: jms_serializer.doctrine_object_constructor
    

    important fact is the @doctrine_mongodb as argument for jms_serializer.doctrine_object_constructor instead the original doctrine parameter in the bundle's services.xml:

        <service id="jms_serializer.doctrine_object_constructor" class="%jms_serializer.doctrine_object_constructor.class%" public="false">
            <argument type="service" id="doctrine"/>
            <argument type="service" id="jms_serializer.unserialize_object_constructor"/>
        </service>
        <service id="jms_serializer.unserialize_object_constructor" class="%jms_serializer.unserialize_object_constructor.class%" public="false" />
        <service id="jms_serializer.object_constructor" alias="jms_serializer.unserialize_object_constructor" public="false" />
    
    0 讨论(0)
提交回复
热议问题