Если объект A содержит несколько объектов B и имеет каскад: persist, как повторно использовать существующие объекты B при сохранении?
Объект B имеет один первичный ключ, целое число и идентификатор родительского элемента A. Единственные данные, которые он содержит, это первичный ключ.
Пример:
A имеет 2 объекта B, идентифицированных по их идентификаторам, 14 и 23.
A.Bs = [{id=14, AId=A.id}, {id=23, AId=A.Id}]
Теперь, если я изменю этот управляемый объект, добавим в A объект B с id = 56.
A.Bs = [{id=14, AId=A.id}, {id=23, AId=A.Id}, {id=56}]
Отношения
Сущность A
/**
* @var B[]|ArrayCollection
*
* @ORM\OneToMany(targetEntity="B", mappedBy="A", cascade={"persist", "remove"}, orphanRemoval=true)
* @Assert\Valid
*/
private $Bs;
Сущность B
/**
* @var A
*
* @ORM\ManyToOne(targetEntity="A", inversedBy="Bs")
* @ORM\JoinColumn(name="A_id", referencedColumnName="A_id")
* @Assert\NotNull()
*/
private $A;
Если я пытаюсь сохранить, я получаю Integrity constraint violation
, потому что Doctrine пытается сохранить существующие сущности с идентификаторами 14 и 23.
Я понимаю, что это ожидаемое поведение, но как я могу заставить его сохранять новые сущности и повторно использовать существующие?
Подробнее:
Если я получу существующую сущность A с $em->find($id)
и напрямую использую persist и flush, я получу UniqueConstraintException
, потому что она пытается сохранить уже сохраненную сущность B.
Пример кода:
/** @var A $existingEntityA */
$existingEntityA = $this->getEntity($id);
$this->serializerFactory->getComplexEntityDeserializer()->deserialize(json_encode($editedEntityADataJson), A::class, 'json', ['object_to_populate' => $existingEntityA]);
$this->entityValidator->validateEntity($existingEntityA);
$this->_em->flush();
Пример ошибки: нарушение ограничения целостности: 1062 Повторяющаяся запись '777111' для ключа 'ПЕРВИЧНАЯ'