在symfony2中,使用jmsSerializerBundle序列化然后反序列化子实体会在保存父实体时引发异常

在symfony2中,使用jmsSerializerBundle序列化然后反序列化子实体会在保存父实体时引发异常,symfony,doctrine-orm,jmsserializerbundle,Symfony,Doctrine Orm,Jmsserializerbundle,我的应用程序有一个名为client的实体,它被注入到每个请求对象中 为了提高性能,我设置了一个自定义缓存,并使用JMSSerializer序列化和缓存客户机对象。当请求传入时,缓存返回序列化的客户机对象,JMS将其反序列化 我的应用程序创建其他实体,称它们为ChildEntity,并通过ChildEntity上的多通关系将它们与客户端对象关联 在我开始通过对缓存数据进行反序列化来加载这些对象,而不是使用条令从MySQL数据库加载它们之前,这一切都很正常。条令现在抛出了这个错误: 通过关系\acm

我的应用程序有一个名为client的实体,它被注入到每个请求对象中

为了提高性能,我设置了一个自定义缓存,并使用JMSSerializer序列化和缓存客户机对象。当请求传入时,缓存返回序列化的客户机对象,JMS将其反序列化

我的应用程序创建其他实体,称它们为ChildEntity,并通过ChildEntity上的多通关系将它们与客户端对象关联

在我开始通过对缓存数据进行反序列化来加载这些对象,而不是使用条令从MySQL数据库加载它们之前,这一切都很正常。条令现在抛出了这个错误:

通过关系\acme\bundle\entity\ChildEntityclient找到了一个新实体,该关系未配置为级联entity:ClientName的持久化操作。要解决此问题,请在此未知实体上显式调用EntityManagerpersist,或在映射中配置cascade persist此关联,例如@ManyTone..,cascade={persist}

因此,如果我正确地理解了这个错误,那么Doctrine似乎认为我的客户机对象(由ChildEntity对象上的多通关系引用)是一个新对象,尽管我正在用它需要保存的ID对其进行反序列化,但不会,因为没有设置级联


我反序列化对象的策略是否错误?是否有某种方法将它们反序列化为代理对象,或者有其他方法解决此问题?我更喜欢使用我的自定义缓存而不是条令缓存。

当我最终找到正确的搜索短语时,我找到了这个

我使用的是默认的对象构造函数,我需要使用条令对象构造函数

为此,我在我的服务中添加了以下内容。yml:

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

我也使用这个模块,并以json格式在会话中保留一个序列化的条令实体

因此,我发现我必须配置Spea/JMSSerializerModule以使用DoctrineObjectConstructor而不是UnserializeObjectConstructor

但是,与UnserializeObjectConstructor相反,DoctrineObjectConstructor不是一个简单的可调用类。构造函数需要两个对象:

接口原则\Common\Persistence\ManagerRegistry$ManagerRegistry 接口JMS\Serializer\Construction\ObjectConstructor接口$fallbackConstructor 问题是没有接口管理器注册的实现,显然也没有工厂

我通过在composer.json中添加此依赖项来解决此问题。此模块通过service manager条目原则\ManagerRegistry提供接口ManagerRegistry的实现

安装后,我为DoctrineObjectConstructor创建了一个工厂:

<?php
namespace Example\Service;

use Zend\ServiceManager\FactoryInterface;
use Zend\ServiceManager\ServiceLocatorInterface;
use JMS\Serializer\Construction\DoctrineObjectConstructor;

class DoctrineObjectConstructorFactory implements FactoryInterface
{
    /* (non-PHPdoc)
     * @see \Zend\ServiceManager\FactoryInterface::createService()
     */
    public function createService(ServiceLocatorInterface $serviceLocator)
    {
        $serv1 = $serviceLocator->get('Doctrine\ManagerRegistry');
        $serv2 = $serviceLocator->get('jms_serializer.unserialize_object_constructor');
        $service = new DoctrineObjectConstructor($serv1, $serv2);
        return $service;
    }
就这样。现在,它起作用了

我在这里写了一个问题:因为我认为我们不应该添加外部模块来完成这项工作

'service_manager' => array(
    'factories' => array(
        'jms_serializer.doctrine_object_constructor' => 'Example\Service\DoctrineObjectConstructorFactory'
    ),
    'aliases' => array(
        'jms_serializer.object_constructor' => 'jms_serializer.doctrine_object_constructor'
    ),
),