transferData($toKeep, $toDelete); // Update linked entities $this->updateReferences($toKeep, $toDelete); $this->em->remove($toDelete); $this->em->flush(); } private function transferData(AccompanyingPeriodWork $toKeep, AccompanyingPeriodWork $toDelete): void { $excludedProperties = ['id', 'createdAt', 'createdBy', 'updatedAt', 'updatedBy']; $reflection = new \ReflectionClass(AccompanyingPeriodWork::class); foreach ($reflection->getProperties() as $property) { if (in_array($property->getName(), $excludedProperties, true)) { continue; } $toKeepValue = $property->getValue($toKeep); $toDeleteValue = $property->getValue($toDelete); if (null === $toKeepValue && null !== $toDeleteValue) { $property->setValue($toKeep, $toDeleteValue); } if ($toKeepValue instanceof Collection && $toDeleteValue instanceof Collection) { foreach ($toDeleteValue as $item) { if (!$toKeepValue->contains($item)) { $toKeepValue->add($item); } } } } } private function updateReferences(AccompanyingPeriodWork $toKeep, AccompanyingPeriodWork $toDelete): void { $allMeta = $this->em->getMetadataFactory()->getAllMetadata(); foreach ($allMeta as $meta) { foreach ($meta->getAssociationMappings() as $assoc) { if (AccompanyingPeriodWork::class !== $assoc['targetEntity']) { continue; // Skip unrelated associations } $entityClass = $meta->getName(); $associationField = $assoc['fieldName']; if ($assoc['type'] & ClassMetadata::TO_ONE) { // Handle ManyToOne or OneToOne $qb = $this->em->createQueryBuilder(); $qb->update($entityClass, 'e') ->set("e.{$associationField}", ':toKeep') ->where("e.{$associationField} = :toDelete") ->setParameter('toKeep', $toKeep) ->setParameter('toDelete', $toDelete) ->getQuery() ->execute(); } if ($assoc['type'] & ClassMetadata::TO_MANY) { // Handle ManyToMany or OneToMany (inverse side) $repo = $this->em->getRepository($entityClass); $linkedEntities = $repo->createQueryBuilder('e') ->join("e.{$associationField}", 't') ->where('t = :toDelete') ->setParameter('toDelete', $toDelete) ->getQuery() ->getResult(); foreach ($linkedEntities as $entity) { $getter = 'get'.ucfirst($associationField); $setter = 'set'.ucfirst($associationField); $adder = 'add'.ucfirst(rtrim($associationField, 's')); $remover = 'remove'.ucfirst(rtrim($associationField, 's')); if (method_exists($entity, $getter) && method_exists($entity, $setter)) { // For OneToMany owning side $collection = $entity->{$getter}(); if ($collection->contains($toDelete)) { $collection->removeElement($toDelete); if (!$collection->contains($toKeep)) { $collection->add($toKeep); } } } elseif (method_exists($entity, $adder) && method_exists($entity, $remover)) { // For ManyToMany $entity->{$remover}($toDelete); $entity->{$adder}($toKeep); } $this->em->persist($entity); } } } } $this->em->flush(); } }