存储库方法并不总是给出预期的结果

时间:2016-01-15 17:00:35

标签: php symfony doctrine-orm doctrine

我有一个奇怪的Symfony / Doctrine错误。 我的实体结构就像这样

class ClassA {

/**
* @ORM\ManyToOne(targetEntity="My\CoreBundle\Entity\ClassB", inversedBy="classAs", cascade={"persist"})
* @ORM\JoinColumn(nullable=false)
*/
private $classB;

}

class ClassB {

/**
 * @ORM\OneToMany(targetEntity="My\CoreBundle\Entity\ClassA", mappedBy="classB", cascade={"persist", "remove"})
 */
private $classAs;

/**
* @ORM\ManyToOne(targetEntity="My\CoreBundle\Entity\ClassC", inversedBy="classBs")
* @ORM\JoinColumn(nullable=false)
*/
private $classC;

}

class ClassC {

/**
* Inverse Side
* @ORM\OneToMany(targetEntity="My\CoreBundle\Entity\ClassB", mappedBy="classC", cascade={"persist", "remove"})
*/
private $classBs;

/**
* Inverse Side
* @ORM\OneToMany(targetEntity="My\CoreBundle\Entity\ClassD", mappedBy="classCs", cascade={"persist", "remove"})
*/
private $classDs;

}

class ClassD {

/**
* @ORM\ManyToOne(targetEntity="My\CoreBundle\Entity\ClassC", inversedBy="classDs")
* @ORM\JoinColumn(nullable=false)
*/
private $classC;

}

我知道在数据库中ClassA(id = 566208)链接到ClassD(id = 16286)。

我在ClassARepository中有这个非常简单的方法。

class ClassARepository extends EntityRepository
{
    public function myMethod()
    {
        $builder = $this->createQueryBuilder('classA');
        $query = $builder->getQuery();

        $classAs = $query->getResult();

        echo "<pre>";
        foreach ($classAs as $classA) {
            if ($classA->getId() == 566208)
            {
                echo "classA 566208\n";
                $classDs = $classA->getClassB()->getClassC()->getClassDs();
                $found = false;
                foreach ($classDs as $classD) {
                    if (16286 == $classD->getId()) {
                            $found = true;
                            echo "INFO 16286 found\n";
                    }
                }
                if (false == $found) echo "ERROR 16286 Not found\n";
            }
        }
        echo "</pre>";
  }
}

当我在控制器中调用此方法时没问题

class MyController
{
    public function indexAction()
    {
        $this->getRepository('MyCoreBundle:ClassA')->myMethod();

    // [...]
    }
}

结果是

classA 566208
INFO 16286 found

但是在代码的其他部分

class MyService
{
    private function myServiceMethod()
    {
        $this->doctrine->getManager()
                        ->getRepository('MyCoreBundle:ClassA')->myMethod();
    }
}

结果是

classA 566208
ERROR 16286 Not found

这会导致什么?我有点困惑,不知道我的学说是否可靠。

我的配置     “php”:“&gt; = 5.5”,     “symfony / symfony”:“2.8。*”,     “doctrine / orm”:“~2.5”,

我做了MySQL检查,一切似乎都没问题。

修改/ TLDR:

此代码......

echo "<pre>";
echo "NORMAL\n";
$classC = $this->doctrine->getManager()->getRepository('MyCoreBundle:ClassC')->find(7);
$classDs = $classC->getClassDs();
$found = false;
foreach ($classDs as $classD) {
    if (16286 == $classD->getId()) {
            $found = true;
            echo "INFO 16286 found\n";
    }
}
if (false == $found) echo "ERROR 16286 Not found\n";

echo "INVERSED\n";
$classDs = $this->doctrine->getManager()->getRepository('MyCoreBundle:ClassD')->findBy(array("classC" => 7));
$found = false;
foreach ($classDs as $classD) {
    if (16286 == $classD->getId()) {
            $found = true;
            echo "INFO 16286 found\n";
    }
}
if (false == $found) echo "ERROR 16286 Not found\n";
echo "</pre>";

...给出...

NORMAL
ERROR 16286 Not found
INVERSED
INFO 16286 found

2 个答案:

答案 0 :(得分:1)

问题是在服务myMethod调用之前执行了查询,而Doctrine放入了缓存这些查询的一些子部分。

解决方案是要求实体经理清除其缓存。

$this->doctrine->getManager()->clear();
$this->doctrine->getManager()
                    ->getRepository('MyCoreBundle:ClassA')->myMethod();

答案 1 :(得分:0)

如果您只查询此ID,则不必也不应该遍历每个表记录(如果不需要)。像这样:

$this->doctrine->getManager->getRepository->('MyCoreBundle:ClassA')->find(16286)

效率更高。您可以从存储库中选择entityManager并获取classC的存储库,并直接使用id查询。

你确定没有什么改变两个方法调用之间的关系吗?

我现在使用Doctrine已经有一段时间了,而且还在制作中,但我还没有这样的问题。