symfony 理论实体管理器的getReference()

8qgya5xd  于 12个月前  发布在  其他
关注(0)|答案(4)|浏览(98)

情况:

我想使用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()来告诉我们这个对象是否真的存在于数据库中?

cl25kdpy

cl25kdpy1#

没有办法让getReference()检查数据库是否存在引用的对象。
实际上,这就是getReference()和它返回的代理的全部内容:创建占位符对象(代理)而不去数据库。你很少想显式地这样做。通常,Doctrine在内部对实体进行水合时会这样做,以便基于外键值为相关实体创建延迟加载占位符。
为什么不直接在Entity Manager上调用find()呢?您是否知道,只要您通过ID查找同一对象,EM就不会多次查询DB?Doctrine会跟踪Unit Of Work中已经水合的对象,并在后续的find()调用中返回对现有对象的引用。

cmssoen2

cmssoen22#

如果你使用getReference来获取一个对象,然后调用一个方法,比如getName,那么Doctrine将从数据库中获取实体。它没有其他方法来找到属性(getName)。

关于您的挑战:

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

bt1cpqcv

bt1cpqcv3#

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

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

字符串
其中$this->doctrine是您的权限管理器

km0tfn4u

km0tfn4u4#

错误代码:

$user = $this->getReference(UserFixtures::USER, User::class);

        $news1 = (new News())
            ->setHeader('news test #1')
            ->setText('news test text #1')
            ->setTimePublic('11:00')
            ->setInitiator($user)
        ;

字符串
成功时,单独二传手:

$user = $this->getReference(UserFixtures::USER, User::class);

    $news1 = (new News())
        ->setHeader('news test #1')
        ->setText('news test text #1')
        ->setTimePublic('11:00')
    ;
    $news1->setInitiator($user);

相关问题