11

情况:

我想使用doctrine2 Entity Manager 的getReference()函数。但是,在我请求一个已从数据库中删除的对象的情况下,如果我多次请求同一个对象,我将获得一个代理。

一个例子:

//A random article object...that has been deleted from the database
$articleClass = 'Acme\ArticleBundle\Entity\Article';
$articleIdentifiers = array('id'=>1);
$i = 0;

//We ask for its reference twice
do{
    try {
        echo "a";
        $subject = $this->em->getReference(
            $subjectClass,
            $subjectIdentifiers
        );
       //call this object now
       var_dump($subject);

    } catch (\Exception $e) {
        echo "b";
    }
    $i++;
} while ($i <2);

输出:

a
b
a
object(Proxies\__CG__\Acme\ArticleBundle\Entity\Article)

如何获取数据库中甚至不存在的对象的代理?如果我评论这一行,entityManager 不会管理对象并且我会获得输出abab,这对我来说更有意义,因为我不想获得数据库中不存在的代理对象。对于信息,返回的代理对象具有其所有属性null。因此,我获得了数据库中不存在的对象的代理。所以,如果我要求这个对象,我会得到一个“未找到实体”异常。

挑战

任何人都可以理解这一点吗?有没有办法依靠getReference()来告诉我们这个对象是否真的存在于数据库中?

4

3 回答 3

23

无法getReference()检查数据库是否存在引用的对象。

实际上,这就是getReference()它返回的代理的全部内容:创建占位符对象(代理)而不进入数据库。而且你很少想明确地这样做。通常,Doctrine 在为基于外键值的相关实体创建延迟加载占位符时在内部执行此操作。

为什么不直接调用find()实体管理器?您是否知道,只要您通过 ID 查找, EM 就不会多次查询同一对象的数据库吗?Doctrine 跟踪工作单元中已经水合的对象,并在后续find()调用中返回对现有对象的引用。

于 2013-06-04T20:15:05.690 回答
2

如果你getReference用来获取一个对象,然后在其上调用一个方法,例如getNameDoctrine 将从数据库中获取实体。它没有其他方法可以找出属性 (getName)。


关于你的挑战:

EntityManager->contains($entity)将是检查来自学说的实体是否在实体管理器中的首选方法

于 2015-10-16T09:58:15.993 回答
0

您需要获取参考并检查数据库中是否包含:

$classChild = $this->doctrine->getReference($classReference, $id);                                
if (!$this->doctrine->contains($classChild)) {
    throw new \Exception("Invalid Reference");
}

$this->doctrine 是你的 EntityManager

于 2019-05-03T18:11:03.613 回答