儿童计数取决于测试方法

Children count depends on method in test

在试验自引用 ManyToOne 实体时,我发现子实体的数量取决于用于查找父实体的方法。如果使用存储库,则测试失败并显示 Failed asserting that 1 matches expected 2。如果改为使用 DQL,则测试成功。请参阅下面测试部分中的 testTwoKids()。我已经在调试中确认在这两种情况下数据库中的实际计数都是 2。

我猜实体定义有问题。

实体:

class Category
{
    /**
     * @var integer
     *
     * @ORM\Column(name="id", type="integer", nullable=false)
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="IDENTITY")
     */
    protected $id;

    /**
     * @ORM\Column(name="name", type="string", nullable=false)
     */
    private $name;

    /**
     * @ORM\OneToMany(targetEntity="Category", mappedBy="parent")
     **/
    private $children;

    /**
     * @ORM\ManyToOne(targetEntity="Category", inversedBy="children", cascade={"persist","remove"})
    *  @ORM\JoinColumn(name="parent_id", referencedColumnName="id")
     **/
    private $parent;

    public function __construct() {
        $this->children = new ArrayCollection();
    }

    public function addChildren($child)
    {
        $this->children[] = $child;

        return $this;
    }

    public function setName($name)
    {
        $this->name = $name;
    }

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

    public function setParent($parent)
    {
        $this->parent = $parent;
    }

    public function getParent()
    {
        return $this->parent;
    }

    /**
     * Get id
     *
     * @return integer 
     */
    public function getId()
    {
        return $this->id;
    }

    /**
     * Add children
     *
     * @param \AppBundle\Entity\Category $children
     * @return Category
     */
    public function addChild($child)
    {
        $this->children->add($child);
        $child->setParent($this);

        return $this;
    }

    /**
     * Remove children
     *
     * @param \AppBundle\Entity\Category $children
     */
    public function removeChild(\AppBundle\Entity\Category $children)
    {
        $this->children->removeElement($children);
    }

    /**
     * Get children
     *
     * @return \Doctrine\Common\Collections\Collection 
     */
    public function getChildren()
    {
        return $this->children;
    }
}

测试

class CategoryTest extends KernelTestCase
{

    /**
     * @var \Doctrine\ORM\EntityManager
     */
    private $em;

    /**
     * {@inheritDoc}
     */
    public function setUp()
    {
        self::bootKernel();
        $this->em = static::$kernel->getContainer()
                ->get('doctrine')
                ->getManager()
        ;
        $product = new \AppBundle\Entity\Product();
        $product->setName('foo');
        $this->em->persist($product);

        $cat = new \AppBundle\Entity\Category();
        $cat->setName('Hook');

        $child = new \AppBundle\Entity\Category();
        $child->setName('Dry');
        $child->setParent($cat);
        $this->em->persist($child);

        $this->em->flush();
    }

    public function testTwoKids()
    {
        $c = $this->em->getRepository('AppBundle:Category')->findOneBy(['name' => 'Hook']);
        $cat = new \AppBundle\Entity\Category();
        $cat->setName('Wet');
        $this->em->persist($cat);
        $c->addChild($cat);
        $this->em->persist($c);
        $this->em->flush();

        /* this returns 1 */
        $c2 = $this->em->getRepository('AppBundle:Category')->findOneBy(['name' => 'Hook']);
        $children = $c2->getChildren();
        $this->assertEquals(2, count($children));

        /* this returns 2 */
//        $id = $c2->getId();
//        $children = $this->em->createQuery("SELECT c FROM AppBundle:Category c WHERE c.parent = $id")
//                ->getResult();
//       $this->assertEquals(2, count($children));

            }

也请在上次冲水后尝试 运行 $this->em->clear()。可能是Doctrine entity manager缓存或者结果缓存导致的。