phpstan-doctrine icon indicating copy to clipboard operation
phpstan-doctrine copied to clipboard

False positive for targetEntity interface

Open eerison opened this issue 2 years ago • 7 comments

I'm not sure if it's a false positive or not, But I didn't know what to put in the title 😄

But I have this Interface

<?php

namespace App\Entity;

use Symfony\Component\Security\Core\User\UserInterface as BaseUserInterface;

interface UserInterface extends BaseUserInterface
{
    public function getId(): int;

    public function getEmail(): string;
}

and my User entity implements this interface

But for entities that join with user I'm getting this error

Property App\Entity\UserSocialNetworking::$user type mapping mismatch: property can contain App\Entity\UserInterface but database expects App\Entity\User.
    // UserSocialNetworking
    #[ORM\ManyToOne(targetEntity: User::class, inversedBy: 'userSocialNetworks')]
    #[ORM\JoinColumn(name: 'user_id', nullable: false)]
    protected UserInterface $user;

I tried to use this: https://symfony.com/doc/current/doctrine/resolve_target_entity.html But it doesn't work too!

any idea?

eerison avatar Aug 06 '22 17:08 eerison

Why not protected User $user;?

ondrejmirtes avatar Sep 21 '22 13:09 ondrejmirtes

Why not protected User $user;?

Hmmmmm I don't remember to have test like it! I'll test and put here the results

eerison avatar Sep 21 '22 13:09 eerison

I ran into a similar issue, I used MediaInterface everywhere but PHPStan still complained about the type mismatch.

This is my original definition:

#[ORM\ManyToOne(targetEntity: MediaInterface::class)]
#[ORM\JoinColumn(name: 'icon_id', referencedColumnName: 'id', onDelete: 'SET NULL')]
private ?MediaInterface $icon = null;

PHPStan was happy after I changed the code to make use of the Media entity:

#[ORM\ManyToOne(targetEntity: Media::class)]
#[ORM\JoinColumn(name: 'icon_id', referencedColumnName: 'id', onDelete: 'SET NULL')]
private ?Media $icon = null;

Interestingly, PHPStan only failed in CI. It worked fine locally. Could not figure why, the set-up locally and in CI looks identical to me.

shochdoerfer avatar Dec 10 '22 11:12 shochdoerfer

Hi

I'm facing the same issue. I'm using interfaces for my entites to decouple them from doctrine. Using User as typehint for the private property doesn't work as the setter method also requires the parameter to implement the UserInterface. I also configured a target entity resolver as the doctrine documentation suggests.

Why not protected User $user;?

    #[ORM\ManyToOne(targetEntity: UserInterface::class)]
    #[ORM\JoinColumn(name: 'user_id', referencedColumnName: 'id', nullable: false, onDelete: 'CASCADE')]
    private UserInterface $user;

    public function setUser(UserInterface $user): FavoriteInterface
    {
        $this->user = $user;
        return $this;
    }

    public function getUser(): UserInterface
    {
        return $this->user;
    }
Property Favorite::$user type mapping mismatch: property can contain UserInterface but database expects User

usox avatar Feb 26 '23 11:02 usox

Same issue with Collections

/**
 * @var Collection<int, AttributeInterface>
 */
#[ORM\OneToMany(mappedBy: "group", targetEntity: AttributeInterface::class)]
protected Collection $attributes;
Property RZ\Roadiz\CoreBundle\Entity\AttributeGroup::$attributes type mapping mismatch: property can contain Doctrine\Common\Collections\Collection<int, RZ\Roadiz\CoreBundle\Model\AttributeInterface> but database expects Doctrine\Common\Collections\Collection&iterable<RZ\Roadiz\CoreBundle\Entity\Attribute>.

ambroisemaupate avatar May 19 '23 15:05 ambroisemaupate

Any solution for this issue?

mabumusa1 avatar May 22 '23 22:05 mabumusa1

I ended up ignoring the error in the configuration :

    ignoreErrors:
        - '/Property .* type mapping mismatch: property can contain .*Interface.* but database expects .*/'

If the mapping is wrong, then bin/console doctrine:schema:validate should return an error.

fred-dedi avatar Nov 21 '23 11:11 fred-dedi