我有一个带有fos restbundle的Symfony rest api构建,并且我反序列化了一个json PUT请求,以便更新具有to-many关系的doctrine实体。
但是,配置有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对象。
但是当我坚持下去时,我希望doctrine从数据库中删除exportDestination,因为我有orphanremoval=true
。
我认为问题是,在反序列化过程中永远不会调用removeExportDestination()
方法,应该在反向方面将关系设置为null。如果这没有发生,它将不会删除该实体,因为它还没有成为一个孤儿。
在反序列化过程中,JMS是否有一种方法可以使用ArrayCollections的添加/删除方法?
我还尝试使用merge()
代替persist()
,但没有任何区别
答案 0 :(得分:2)
你是对的&#34;在反序列化期间永远不会调用removeExportDestination()方法&#34;。
您可以定义访问者属性来执行您想要的操作:
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);
}
}
以便在反序列化期间&#34; setExportDestinations&#34;被调用,它负责删除关系。
话虽如此,我不确定你是否应该在关系上使用orphanremoval=true
orphanRemoval = true,即使你要从一个ExportJob中删除给定的ExportDestination,然后附加到另一个ExportJob,这个ExportDestination也会在persist期间删除,因为该引用已被删除。
我建议删除它并找到另一种方法来删除&#34; orphan&#34; ExportDestination实体。