symfony icon indicating copy to clipboard operation
symfony copied to clipboard

[Mapper] - only the last target is used

Open vencakrecl opened this issue 1 month ago • 2 comments

Symfony version(s) affected

7.3

Description

<?php

namespace App\Entity;

use App\Resource\V1\RoleResource as RoleResourceV1;
use App\Resource\V2\RoleResource as RoleResourceV2;
use Symfony\Component\ObjectMapper\Attribute\Map;

#[Map(target: RoleResourceV2::class)]
#[Map(target: RoleResourceV1::class)]
class Role
{
    public function __construct(public readonly int $id)
    {

    }
}

issue:

App\Resource\V2\ObjectResource::__construct(): Argument #1 ($role) must be of type App\Resource\V2\RoleResource, App\Resource\V1\RoleResource given, called in /Users/vencakrecl/Projects/venca/symfony_issue_mapper/vendor/symfony/object-mapper/ObjectMapper.php on line 170

How to reproduce

https://github.com/vencakrecl/symfony_issue_62593

git clone [email protected]:vencakrecl/symfony_issue_62593.git

cd symfony_issue_62593

php -S localhost:8000 -t public 

curl http://localhost:8000/object-1
curl http://localhost:8000/object-2 # fail

Possible Solution

No response

Additional Context

No response

vencakrecl avatar Dec 01 '25 11:12 vencakrecl

I don't think this is about the namespace. If you change the names of the Resources classes it will also fail.

App\Resource\V1\ObjectResource -> App\Resource\V1\AnotherObjectResource
App\Resource\V1\RoleResource-> App\Resource\V1\AnotherRoleResource

It's more like only the last target in Role.php is being used.

#[Map(target: RoleResourceV2::class)]
#[Map(target: RoleResourceV1::class)]
class Role
{
    public function __construct(public readonly int $id)
    {

    }
}

You can try to define some extra props on RoleResource on each ns and you will find out.


namespace App\Resource\V1;

class RoleResource
{
    public int $add;
    public function __construct(public readonly int $id) {
        $this->add = 100 + $id;
    }
}

# -----

namespace App\Resource\V2;

class RoleResource
{
    public int $add;
    public function __construct(public readonly int $id) {
        $this->add = 200 + $id;
    }
}

# --- 
# And then allow type on each constructor

namespace App\Resource\V2;

use App\Resource\V1\RoleResource as V1;

class ObjectResource
{
    public function __construct(public readonly RoleResource|V1 $role)
    {

    }
}

I don't know if this is intended behaviour

fperxas avatar Dec 01 '25 13:12 fperxas

@fperxas good point 👍. Only the last target is used.

vencakrecl avatar Dec 01 '25 16:12 vencakrecl