Skip to content

Conversation

soyuka
Copy link
Member

@soyuka soyuka commented Jul 18, 2025

Q A
Branch? main
License MIT

Fixes an issue where we keep fetched relations so that we don't create new entities instead of persisting the existing one. Check the test and the issue at symfony/symfony#61119.

This needs symfony/symfony#61145 to work.


public function map(object $source, object|string|null $target = null): object
{
if (isset($this->objectMap[$source])) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't we want to check if a target has not been given explicitly by the user before overriding it?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In my tests the target is a string and I do need to map but I'll test this further.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree, if the target is an object it shouldn't be overridden.

@mrossard
Copy link
Contributor

mrossard commented Jul 25, 2025

I was taking a look at the ObjectMapper, and I have doubts about simple patches in the current implementation - if you add $this->assertEquals($uri, $r->toArray()['@id']); here : https://github.com/api-platform/core/blob/main/tests/Functional/MappingTest.php#L69 you get this :

1) ApiPlatform\Tests\Functional\MappingTest::testShouldMapBetweenResourceAndEntity
Failed asserting that two strings are equal.
--- Expected
+++ Actual
@@ @@
-'/mapped_resources/11'
+'/mapped_resources/12'

Would this fix work on this too?

[edit]

Yes, it should.

$target = $this->objectMap[$source];
}
$mapped = $this->decorated->map($source, $target);
$this->objectMap[$mapped] = $source;
Copy link
Contributor

@mrossard mrossard Jul 26, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't you also add $this->objectMap[$source] = $target; ? In persist operations you have multiple back and forth mappings between resource and entity.

This probably should be indexed by the object class too, otherwise multiple mappings will not work - you'll get errors similar to what was fixed by #7311

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you have a test case for this?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll try to build one, but you can imagine something like a resource that includes 2 different subresources that are actually representations of the same entity. You'd be storing that $entity maps to $firstResource, then on the call for SecondResource::class you'd get back $firstResource.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

...and if it was about the first part of my comment, ObjectMapperProcessor does the transformation both ways :

  • first the resource is mapped to the entity
  • the entity is persisted
  • the entity is mapped back to the resource

But as i'm writing this i realize it shouldn't reuse the previous object since its contents can change on persist, so you can just ignore my ramblings :D


public function map(object $source, object|string|null $target = null): object
{
if (isset($this->objectMap[$source])) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree, if the target is an object it shouldn't be overridden.

@soyuka soyuka force-pushed the object-mapper-with-relations-put branch 4 times, most recently from a9844d7 to e3a23b7 Compare July 29, 2025 07:26
@soyuka soyuka force-pushed the object-mapper-with-relations-put branch from e3a23b7 to 024b431 Compare July 29, 2025 07:29
@soyuka soyuka merged commit d06b1a0 into api-platform:main Jul 29, 2025
113 of 114 checks passed
@soyuka soyuka deleted the object-mapper-with-relations-put branch July 29, 2025 08:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants