【问题标题】:JMS unserialize to-many relation does not remove with orphanremovalJMS 反序列化对多关系不会通过 orphanremoval 删除
【发布时间】:2018-09-09 10:41:52
【问题描述】:

我有一个带有 fos restbundle 的 Symfony rest api 构建,并且我正在反序列化一个 json PUT 请求,以便更新具有一对多关系的学说实体。 但是,配置了orphanremoval=true 的to-many 子对象在json 数据中不存在时不会从数据库中删除。

PUT 请求负载:

{
    "id": 1,
    "name":"Some name",
    "export_destinations": [
        {
            "id": 1,
            "type": "USER_STORAGE",
            "user": {"id": 5}
        }
        {
            "id": 2,
            "type": "SYSTEM_STORAGE"
        }
    ]
}

控制器动作:

 /**
  * @Rest\Put("{id}")
  * @ParamConverter(
  *     "exportJob",
  *     converter="fos_rest.request_body",
  *     options={"deserializationContext"={"groups"={"put"}}}
  * )
  * @Rest\View(serializerGroups={"details"})
  * @param ExportJob $exportJob
  * @return ExportJob
  */
public function putAction(ExportJob $exportJob)
{
    $this->getManager()->persist($exportJob);
    $this->getManager()->flush();

    return $exportJob;
}

ExportJob 实体

/**
 * @ORM\Entity()
 */
class ExportJob
{
    /**
     * @var ArrayCollection|ExportDestination[]
     *
     * @ORM\OneToMany(targetEntity="ExportDestination", mappedBy="exportJob", cascade={"persist", "remove", "merge"}, orphanRemoval=true)
     */
    protected $exportDestinations;

    /**
     * @param ExportDestination $exportDestination
     * @return $this
     */
    public function addExportDestination(ExportDestination $exportDestination)
    {
        $exportDestination->setExportJob($this);
        $this->exportDestinations->add($exportDestination);

        return $this;
    }

    /**
     * @param ExportDestination $exportDestination
     * @return $this
     */
    public function removeExportDestination(ExportDestination $exportDestination)
    {
        $this->exportDestinations->removeElement($exportDestination);
        $exportDestination->setExportJob(null);

        return $this;
    }
}

JMS 元数据

MyProject\ExportBundle\Entity\ExportJob:
    exclusion_policy: ALL
    properties:
        id:
            groups: ['list', 'details', 'put']
            expose: true
        name:
            groups: ['list', 'details', 'put', 'patch', 'post']
            expose: true
        exportDestinations:
            groups: ['details', 'put', 'patch', 'post']
            expose: true
            type: 'ArrayCollection<MyProject\ExportBundle\Entity\ExportDestination>'

我正在使用 DoctrineObjectConstructor

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

现在,当我从 json 有效负载中的 export_destinations 数组中省略第二个对象时,控制器操作中的 exportJob 在反序列化后的数组集合中只有一个 exportDestination 对象。 但是当我坚持时,我希望学说会从数据库中删除 exportDestination,因为我有 orphanremoval=true

我认为问题在于,removeExportDestination() 方法在反序列化过程中永远不会被调用,什么应该在反面将关系设置为 null。如果这没有发生,它不会删除实体,因为它还没有成为孤儿。

JMS 有没有办法在反序列化期间使用 ArrayCollections 的 add/remove 方法?

我也尝试使用merge() 代替persist(),但没有任何区别

【问题讨论】:

  • 能否添加ExportDestination实体代码及其jms元数据?

标签: doctrine-orm fosrestbundle symfony-2.8 jmsserializerbundle


【解决方案1】:

关于“在反序列化期间永远不会调用 removeExportDestination() 方法”,您是对的。

你可以定义 accessor 属性来做你想做的事:

exportDestinations:
        groups: ['details', 'put', 'patch', 'post']
        expose: true
        type: 'ArrayCollection<AppBundle\Entity\ExportDestination>'
        accessor:
            getter: "getExportDestinations"
            setter: "setExportDestinations"

在 ExportJob 实体中:

public function getExportDestinations()
{
    return $this->exportDestinations;
}

public function setExportDestinations($exportDestinations)
{
    // first detach existing related entities.
    foreach ($this->exportDestinations as $exportDestination) {
        $exportDestination->setExportJob(null);
    }
    $this->exportDestinations = $exportDestinations;
    foreach ($exportDestinations as $exportDestination) {
        $exportDestination->setExportJob($this);
    }
}

以便在反序列化过程中调用“setExportDestinations”并负责删除关系。

话虽如此,我不确定你是否应该在关系上使用orphanremoval=true,因为

orphanRemoval=true,即使您将从一个 ExportJob 中删除给定的 ExportDestination,然后附加到另一个 ExportJob,此 ExportDestination 将在持久化期间被删除,因为引用已被删除。

我建议删除它并找到另一种方法来删除“孤立”ExportDestination 实体。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-07-12
    • 2019-09-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-03-13
    • 2019-04-20
    相关资源
    最近更新 更多