Uh oh!
There was an error while loading.Please reload this page.
- Notifications
You must be signed in to change notification settings - Fork9.6k
Description
Symfony version(s) affected
7.3
Description
Hi there,
I'm using Symfony as an Backend-API and have changed the last weeks to use the ObjectMapper.
At updating existing entitys is a problem it doesn't work always. To create an new entity it always works fine. At first I thought it cause of nested entitys, but it's also an "top level" entity. I have two examples for that.
How to reproduce
First example (nested entity)
#Controller.php#[Route('/klasse-turnier-zuord/{klasse_turnier_zuord_id}/edit', name:"turnier-work-klasse-turnier-klasse-zuord-edit", methods: ["PATCH"], format:"json")]publicfunctionklasseEdit( #[MapRequestPayload]KlasseMitTurnierZuordDTO$klasseMitTurnierZuordDTO,int$klasse_turnier_zuord_id, ):JsonResponse{$klasseTurnierZuordAktuell =$this->klasseTurnierZuordRepos->findOneBy(['turnier' =>$this->turnier,'id' =>$klasse_turnier_zuord_id]);if ($klasseTurnierZuordAktuellinstanceof KlasseTurnierZuord) {$klAkt =$klasseTurnierZuordAktuell->getKlasse();$klDTO =$klasseMitTurnierZuordDTO->klasse;// just shorten for the comparison bellow$genAkt = [];foreach ($klAkt->getGender()as$gen) {$genAkt[] =$gen->getId(); }if (($klAkt->getStandard()) && (($klAkt->getName() !=$klDTO->name) || ($klAkt->getBogentyp()->getId() !=$klDTO->bogentyp_id) || ($klAkt->getAltersklasseVon()->getId() !=$klDTO->altersklasse_von_id) || ($klAkt->getAltersklasseBis()->getId() !=$klDTO->altersklasse_bis_id) || ($klAkt->getApollonKlasseNr() !=$klDTO->apollon_klasse_nr) || ($genAkt !=$klDTO->gender_id))) {$this->objectMapper->map($klasseMitTurnierZuordDTO->klasse,$klasseTurnierZuordAktuell->getKlasse());$klasseTurnierZuordAktuell->getKlasse()->unsetId();$klasseTurnierZuordAktuell->getKlasse()->setStandard(false); }else {$this->objectMapper->map($klasseMitTurnierZuordDTO->klasse,$klasseTurnierZuordAktuell->getKlasse()); } }return$this->json([]);}
#KlasseMitTurnierZuordDTO.phpclass KlasseMitTurnierZuordDTO{publicfunction__construct(publicreadonlyKlasseDTO$klasse,publicreadonlyKlasseTurnierZuordDTO$klasse_turnier_zuord, ) { }}
#KlasseDTO.php#[Map(target: Klasse::class)]class KlasseDTO{publicfunction__construct(publicreadonlybool$standard, #[Map(target:"inter_nat", transform: KlasseInterNatTransformer::class)]publicreadonlyarray$inter_nat,publicreadonly ?int$gueltig_von,publicreadonly ?int$gueltig_bis,publicreadonlystring$name, #[Map(target:'bogentyp', transform: BogentypTransformer::class)]publicreadonly ?int$bogentyp_id, #[Map(target:'altersklasse_von', transform: AltersklasseVonTransformer::class)]publicreadonly ?int$altersklasse_von_id, #[Map(target:'altersklasse_bis', transform: AltersklasseBisTransformer::class)]publicreadonly ?int$altersklasse_bis_id,publicreadonly ?int$apollon_klasse_nr, #[Map(target:'gender', transform: GenderTransformer::class)]publicreadonlyarray$gender_id, #[Map(target:'klasse_turniertyp_zuord', transform: KlasseTurniertypZuordTransformer::class)]publicreadonly ?array$turniertyp_zuord =null, ) { }}
On dumping the DTO-object there's the new value, but it isn't mapped to the entity.
I also have tested to don't get the Klasse entity from the $klasseTurnierZuordAktuell, load it with the entity manager by id, but some result.
second example ("top level" entity)
#Controller#[Route('/einstellungen', name:"turnier-work-meldung-einstellungen", methods: ["PATCH"], format:"json")]publicfunctioneinstellungen(#[MapRequestPayload]TurnierMeldungEinstellungenDTO$turnierMeldungEinstellungenDTO):JsonResponse{try {$this->objectMapper->map($turnierMeldungEinstellungenDTO,$this->turnier);$this->eM->persist($this->turnier);$this->eM->flush();$this->eM->refresh($this->turnier);$this->subscriber->setResponseSuccess(true);return$this->json($this->turnier->getArrayOwner()); }catch (Exception$e) {dump($e);$this->subscriber->setResponseError([1,43,1,1]); }return$this->json([]);}
#TurnierMeldungEinstellungenDTO.php#[Map(target: Turnier::class)]class TurnierMeldungEinstellungenDTO{publicfunction__construct( #[Map(target:'meldeschluss_date', transform: DateTimeTransformer::class)]publicreadonlystring$meldeschluss_date,publicreadonlystring$meldung_neu_nach_meldeschluss,publicreadonlybool$meldung_edit_nach_meldeschluss,publicreadonlybool$meldung_delete_nach_meldeschluss,publicreadonlybool$delete_meldung_autoremove_startliste,publicreadonlybool$mehrfach_meldung_moeglich,publicreadonlybool$meldung_ohne_eindeutig_klassenzuordnung,publicreadonlybool$meldung_klassenzuordnung_melder_manuell,publicreadonlybool$melden_mannschaft,publicreadonlybool$meldung_ohne_quali,publicreadonlybool$meldung_ohne_datenpruefung,publicreadonlybool$meldung_ohne_startberechtigung,publicreadonlybool$meldung_check_hoeherstufung, ) { }}
The TurnierMeldungEinstellungenDTO isn't an DTO of the full target, there are only properties how would be changed some settings.
Possible Solution
No response
Additional Context
I have shorten the controller codes for easier to read and understand here. I also have tested the shorten codes, but there's the some problem, so it's not caused on the code around the mapper.
If I exchange the existing entities with empty entities the mapping works well.