学说拆卸,缓存和合并(Doctrine detaching, caching, and mergin

2019-07-03 19:09发布

我在学说2.3。 我有以下查询:

$em->createQuery('
    SELECT u, c, p
    FROM Entities\User u
    LEFT JOIN u.company c
    LEFT JOIN u.privilege p
    WHERE u.id = :id
')->setParameter('id', $identity)

然后我拿去,得到的结果(这是一个数组,我只取第一个元素),并运行分离$em->detach($result);

当我去从缓存中(使用Doctrine的APC高速缓存驱动器)来获取,我做的:

$cacheDriver = new \Doctrine\Common\Cache\ApcCache();
if($cacheDriver->contains($cacheId))
{
    $entity = $cacheDriver->fetch($cacheId);
    $em->merge($entity);
    return $entity;
}

我的希望是,因为还有很多其他的关系绑比在查询中显示的其他用户对象,这将重新启用的实体之间的关系加载。

我想创建这样一个新的实体:

$newEntity = new Entities\ClientType();
$newEntity['param'] = $data;
$newEntitiy['company'] = $this->user['company'];
$em->persist($newEntity);
$em->flush();

当我这样做,我得到一个错误:

A new entity was found through the relationship 'Entities\ClientType#company' that was not configured to cascade persist operations for entity:
Entities\Company@000000005d7b49b500000000dd7ad743. 
To solve this issue: Either explicitly call EntityManager#persist() on this unknown entity or configure cascade persist this association in the mapping for example @ManyToOne(..,cascade={"persist"}). 
If you cannot find out which entity causes the problem implement 'Entities\Company#__toString()' to get a clue.

当我不使用我从缓存中得到了用户的实体下的实体公司这一切正常。 有没有什么办法,使这项工作,所以我不必从数据库中我想在一个关系有一个新的实体使用它每一次重新读取该公司的实体?

编辑:这是我在处理这两个关系的用户实体:

/**
    * @ManyToOne(targetEntity="Company" , inversedBy="user", cascade={"detach", "merge"})
    */
    protected $company;

    /**
    * @ManyToOne(targetEntity="Privilege" , inversedBy="user", cascade={"detach", "merge"})
    */
    protected $privilege;

我仍然得到同样的错误。

第二个编辑:尝试一个$em->contains($this->user);$em->contains($this->user['company']); 这两个返回false。 这听起来...错了。

Answer 1:

当合并一个用户,你想要的关联公司,并荣幸地被合并为好,对吗?

这个过程被称为级联:

http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/reference/working-with-associations.html#transitive-persistence-cascade-operations

在用户实体把cascade={"merge"}@ManyToOne注释(或其他类型的协会定义您正在使用的)为$company$privilege

如果你想得太级联的分离调用(推荐),把在cascade={"detach", "merge"}

PS:不要把这样的级联的一个关联的两边,你将创建一个无限循环;)

编辑:

这一段代码:

$entity = $cacheDriver->fetch($cacheId);
$em->merge($entity);                      // <-
return $entity;

应该:

$entity = $cacheDriver->fetch($cacheId);
$entity = $em->merge($entity);            // <-
return $entity;

用的东西merge()是,它让你通过为不变参数实体,并返回一个代表实体的托管版本的对象。 所以,你要使用的返回值,而不是你传递的参数。



文章来源: Doctrine detaching, caching, and merging