"Warning: Potentially polymorphic call" 在实体存储库上调用方法时

"Warning: Potentially polymorphic call" when calling a method on a entity repository

我的实体 Item 有一个功能为 findItemCount() 的存储库 (ItemRepository)。当我使用

$repository = $em->getRepository(Item::class);    
$items = $repository->findItemCount();

我收到警告:

Potentially polymorphic call. The code may be inoperable depending on the actual class instance passed as the argument.

此外,自动完成功能没有向我建议函数“findItemCount”。我的错误是什么?

控制器:

/**
 * Artikel Liste
 * @Route("/item/list", name="app_item_list")
 * @param EntityManagerInterface $em
 * @return Response
 */
public function listItems(EntityManagerInterface $em): Response
{
    $repository = $em->getRepository(Item::class);
    $items = $repository->findItemCount();

    return $this->render('item_admin/itemList.html.twig', [
        'items' => $items,
        'title' => 'Artikel Übersicht',
        'blocked' => false
    ]);
}

Item.php

<?php

namespace App\Entity;

use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;
use Doctrine\ORM\Mapping\OrderBy;

/**
 * @ORM\Entity(repositoryClass="App\Repository\ItemRepository")
 */
class Item
{
    /**
     * @ORM\Id()
     * @ORM\GeneratedValue()
     * @ORM\Column(type="integer")
     */
    private $id;

    /**
     * @ORM\Column(type="string", length=255)
     * @OrderBy({"name" = "ASC"})
     */
    private $name;

    /**
     * @ORM\Column(type="text", nullable=true)
     */
    private $description;

    /**
     * @ORM\ManyToOne(targetEntity="App\Entity\Itemparent", inversedBy="item")
     */
    private $itemparent;

    /**
     * @ORM\ManyToOne(targetEntity="App\Entity\Itemgroup", inversedBy="items")
     */
    private $itemgroup;

    /**
     * @ORM\Column(type="string", length=255)
     */
    private $minsize;

    /**
     * @ORM\Column(type="boolean")
     */
    private $charge;

    /**
     * @ORM\Column(type="boolean")
     */
    private $blocked;

    /**
     * @ORM\OneToMany(targetEntity="App\Entity\Barcode", mappedBy="item", orphanRemoval=true)
     */
    private $barcodes;

    /**
     * @ORM\OneToMany(targetEntity="App\Entity\ItemStock", mappedBy="item", orphanRemoval=true)
     */
    private $itemStocks;

    /**
     * @ORM\OneToMany(targetEntity="App\Entity\BookingItem", mappedBy="item", orphanRemoval=true)
     */
    private $bookingItems;

    /**
     * @ORM\Column(type="float", nullable=true)
     */
    private $price;

    /**
     * @ORM\OneToMany(targetEntity=SupplierItems::class, mappedBy="item")
     */
    private $supplierItems;

    /**
     * @ORM\OneToMany(targetEntity=ItemStockCharge::class, mappedBy="item")
     */
    private $itemStockCharges;


    public function __construct()
    {
        $this->barcodes = new ArrayCollection();
        $this->itemStocks = new ArrayCollection();
        $this->suppliers = new ArrayCollection();
        $this->supplierItems = new ArrayCollection();
        $this->itemStockCharges = new ArrayCollection();
    }

    public function getId(): ?int
    {
        return $this->id;
    }

    public function getName(): ?string
    {
        return $this->name;
    }

    public function setName(string $name): self
    {
        $this->name = $name;

        return $this;
    }

    public function getDescription(): ?string
    {
        return $this->description;
    }

    public function setDescription(?string $description): self
    {
        $this->description = $description;

        return $this;
    }

    public function getItemparent(): ?Itemparent
    {
        return $this->itemparent;
    }

    public function setItemparent(?Itemparent $itemparent): self
    {
        $this->itemparent = $itemparent;

        return $this;
    }

    public function getItemgroup(): ?Itemgroup
    {
        return $this->itemgroup;
    }

    public function setItemgroup(?Itemgroup $itemgroup): self
    {
        $this->itemgroup = $itemgroup;

        return $this;
    }

    public function getMinsize(): ?string
    {
        return $this->minsize;
    }

    public function setMinsize(string $minsize): self
    {
        $this->minsize = $minsize;

        return $this;
    }

    public function getCharge(): ?bool
    {
        return $this->charge;
    }

    public function setCharge(bool $charge): self
    {
        $this->charge = $charge;

        return $this;
    }

    public function getBlocked(): ?bool
    {
        return $this->blocked;
    }

    public function setBlocked(bool $blocked): self
    {
        $this->blocked = $blocked;

        return $this;
    }

    /**
     * @return Collection|Barcode[]
     */
    public function getBarcodes(): Collection
    {
        return $this->barcodes;
    }

    public function addBarcode(Barcode $barcode): self
    {
        if (!$this->barcodes->contains($barcode)) {
            $this->barcodes[] = $barcode;
            $barcode->setItem($this);
        }

        return $this;
    }

    public function removeBarcode(Barcode $barcode): self
    {
        if ($this->barcodes->contains($barcode)) {
            $this->barcodes->removeElement($barcode);
            // set the owning side to null (unless already changed)
            if ($barcode->getItem() === $this) {
                $barcode->setItem(null);
            }
        }

        return $this;
    }

    /**
     * @return Collection|ItemStock[]
     */
    public function getItemStocks(): Collection
    {
        return $this->itemStocks;
    }

    public function addItemStock(ItemStock $itemStock): self
    {
        if (!$this->itemStocks->contains($itemStock)) {
            $this->itemStocks[] = $itemStock;
            $itemStock->setItem($this);
        }

        return $this;
    }

    public function removeItemStock(ItemStock $itemStock): self
    {
        if ($this->itemStocks->contains($itemStock)) {
            $this->itemStocks->removeElement($itemStock);
            // set the owning side to null (unless already changed)
            if ($itemStock->getItem() === $this) {
                $itemStock->setItem(null);
            }
        }

        return $this;
    }

    /**
     * @return Collection|BookingItem[]
     */
    public function getBookingItems(): Collection
    {
        return $this->bookingItems;
    }

    public function addBookingItem(BookingItem $bookingItem): self
    {
        if (!$this->bookingItems->contains($bookingItem)) {
            $this->bookingItems[] = $bookingItem;
            $bookingItem->setItem($this);
        }

        return $this;
    }

    public function removeBookingItem(BookingItem $bookingItem): self
    {
        if ($this->bookingItems->contains($bookingItem)) {
            $this->bookingItems->removeElement($bookingItem);
            if ($bookingItem->getItem() === $this) {
                $bookingItem->setItem(null);
            }
        }
        return $this;
    }

    public function getPrice(): ?float
    {
        return $this->price;
    }

    public function setPrice(?float $price): self
    {
        $this->price = $price;

        return $this;
    }

    public function getCommaPrice(): string
    {
        return number_format($this->price, 2, ',', '');
    }

    /**
     * @return Collection|SupplierItems[]
     */
    public function getSupplierItems(): Collection
    {
        return $this->supplierItems;
    }

    public function addSupplierItem(SupplierItems $supplierItem): self
    {
        if (!$this->supplierItems->contains($supplierItem)) {
            $this->supplierItems[] = $supplierItem;
            $supplierItem->setItem($this);
        }

        return $this;
    }

    public function removeSupplierItem(SupplierItems $supplierItem): self
    {
        if ($this->supplierItems->contains($supplierItem)) {
            $this->supplierItems->removeElement($supplierItem);
            // set the owning side to null (unless already changed)
            if ($supplierItem->getItem() === $this) {
                $supplierItem->setItem(null);
            }
        }

        return $this;
    }

    /**
     * @return Collection|ItemStockCharge[]
     */
    public function getItemStockCharges(): Collection
    {
        return $this->itemStockCharges;
    }

    public function addItemStockCharge(ItemStockCharge $itemStockCharge): self
    {
        if (!$this->itemStockCharges->contains($itemStockCharge)) {
            $this->itemStockCharges[] = $itemStockCharge;
            $itemStockCharge->setItem($this);
        }

        return $this;
    }

    public function removeItemStockCharge(ItemStockCharge $itemStockCharge): self
    {
        if ($this->itemStockCharges->contains($itemStockCharge)) {
            $this->itemStockCharges->removeElement($itemStockCharge);
            // set the owning side to null (unless already changed)
            if ($itemStockCharge->getItem() === $this) {
                $itemStockCharge->setItem(null);
            }
        }

        return $this;
    }
}

ItemRepository.php

<?php

namespace App\Repository;

use App\Entity\Item;
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
use Doctrine\Common\Persistence\ManagerRegistry;

/**
 * @method Item|null find($id, $lockMode = null, $lockVersion = null)
 * @method Item|null findOneBy(array $criteria, array $orderBy = null)
 * @method Item[]    findAll()
 * @method Item[]    findBy(array $criteria, array $orderBy = null, $limit = null, $offset = null)
 */
class ItemRepository extends ServiceEntityRepository
{
    public function __construct(ManagerRegistry $registry)
    {
        parent::__construct($registry, Item::class);
    }

    public function findItem()
    {
        return $this->createQueryBuilder('a')
            ->andWhere('a.blocked = :val')
            ->setParameter('val', false)
            ->orderBy('a.name', 'ASC')
            ->getQuery()
            ->getResult()
            ;
    }

    public function findBlockedItemCount()
    {
        return $this->createQueryBuilder('item')
            ->select('item, SUM(stocks.count) as sums')
            ->andWhere('item.blocked = :val')
            ->setParameter('val', true)
            ->leftJoin('item.itemStocks', 'stocks')
            ->groupBy('item')
            ->orderBy('item.name', 'ASC')
            ->getQuery()
            ->getResult()
            ;
    }

    public function findItemCount(){
        return $this->createQueryBuilder('item')
            ->select('item, SUM(stocks.count) as sums')
            ->andWhere('item.blocked = :val')
            ->setParameter('val', false)
            ->leftJoin('item.itemStocks', 'stocks')
            ->groupBy('item')
            ->orderBy('item.name', 'ASC')
            ->getQuery()
            ->getResult()
            ;
    }

}

IDE 现在有办法知道 $em->getRepository(Item::class); 将 return ItemRepository,因为直到运行时才解决。

注入 ItemRepository 而不是实体管理器,无论如何这是更好的做法:

public function listItems(ItemRepository $itemRepository): Response
{
    $items = $itemRepository->findItemCount();
    // etc
}