The generated proxy class for an entity has the following code for the getId() method:
/**
* {@inheritDoc}
*/
public function getId(): ?ExampleEnum
{
if ($this->__isInitialized__ === false) {
return (int) parent::getId();
}
$this->__initializer__ && $this->__initializer__->__invoke($this, 'getId', []);
return parent::getId();
}
The problem is the line with return (int) parent::getId(); because it's casting the return value to int, even though the method is expected to return ?ExampleEnum.
Current behavior
An error is thrown:
Proxies\\__CG__\\App\\Entity\\ExampleEntity::getId(): Return value must be of type ?ExampleEnum, int returned
How to reproduce
To reproduce this, you need:
an entity with a PHP enum class as the primary key
a second entity that has a ManyToOne relationship with the first
load an instance of the second entity, and then try to fetch the id of the related entity (the one with the enum PK)
since the related entity is not yet loaded, the proxy method will be used
error occurs
enum ExampleEnum: int
{
Case A = 1;
Case B = 2;
}
class ExampleEntity
{
#[ORM\Column(name: 'id', type: Types::INTEGER, nullable: false, enumType: ExampleEnum::class)]
#[ORM\Id]
#[ORM\GeneratedValue(strategy: 'IDENTITY')]
private ?ExampleEnum $id = null;
public function getId(): ?ExampleEnum
{
return $this->id;
}
}
class AnotherEntity
{
#[ORM\Column(name: 'id', type: Types::INTEGER, nullable: false)]
#[ORM\Id]
#[ORM\GeneratedValue(strategy: 'IDENTITY')]
private ?int $id = null;
public function getId(): ?int
{
return $this->id;
}
#[ORM\ManyToOne(targetEntity: ExampleEntity::class)]
#[ORM\JoinColumn(name: 'entityId', referencedColumnName: 'id', nullable: false)]
private ExampleEntity $relatedEntity;
public function getRelatedEntity: ExampleEntity
{
return $this->relatedEntity;
}
}
$foo = $em->getRepository(AnotherEntity::class)->find(1);
$enum = $foo->getRelatedEntity()->getId(); // fails here
Expected behavior
The getId() method should return the correct enum class instead of an int.
Workaround
Avoid using the proxy by using eager loading, or fetching some other property to initialize the object.
The bug
The generated proxy class for an entity has the following code for the getId() method:
The problem is the line with
return (int) parent::getId();
because it's casting the return value toint
, even though the method is expected to return?ExampleEnum
.Current behavior
An error is thrown:
Proxies\\__CG__\\App\\Entity\\ExampleEntity::getId(): Return value must be of type ?ExampleEnum, int returned
How to reproduce
To reproduce this, you need:
Expected behavior
The getId() method should return the correct enum class instead of an int.
Workaround
Avoid using the proxy by using eager loading, or fetching some other property to initialize the object.
Potential solution
I can see the offending code is here: https://github.com/doctrine/common/blob/0a357f1bb08a95a2b170f7db19c9e775420b40b3/src/Proxy/ProxyGenerator.php#L936-L950
You could simply remove the
$cast
variable, it's not necessary in my opinion, since you already declare the return type thanks to:$this->getMethodReturnType($method)
Thanks!