代码之家  ›  专栏  ›  技术社区  ›  DrKey

条令-代理实体未正确更新

  •  0
  • DrKey  · 技术社区  · 7 年前

    脚本

    • 我有一个实体 Device 它有一个双向的 一个托马尼 与…的关系 Attribute 实体
    • 我有一个cli进程,它监听传入的请求,并最终发送响应
    • 我有一个行为测试,它检查设备属性是否被正确地更改,向所述侦听器发送请求

    行为测试

    这就是发生的事情:

    1. 我得到一个 装置 从数据库到条令库的对象-设备具有 属性 集合尚未初始化(延迟加载)
    2. 因为我需要知道一个特定属性的属性,这个特定属性从条令中加载并初始化——它仍然是一个 Proxy 但是有 __isInitialized__ 设置为 true
    3. 我向侦听器发送请求,请求对此特定设备属性进行更改
    4. 侦听器接收请求并根据请求更改属性值(例如 attribute->setValue(true) )
    5. 侦听器返回一个响应以确认更改
    6. 现在测试通过获取给定设备的属性 属性 实体存储库,以检查其值是否已在侦听器的db中正确更改

    问题出现在第6点: 属性值错误 .

    现在有人可能认为这是正常的,因为对象已经在行为测试中被加载并标记为已初始化,所以条令不知道并发进程所做的更改,这样就可以了。

    然而,真正奇怪的是,无论怎样,条令都在执行第6点的查询(使用条令SQL日志进行检查),并且该查询返回的结果集包含该设备属性的不同值(即 value 属性),但属性变量不会自动更新!

    事实上,为了更新它,我必须打电话给 $em->refresh() 或使用清除缓存 $em->clear() 在第6点获取属性之前。

    这是理论上的错误还是什么?有什么想法吗?

    1 回复  |  直到 7 年前
        1
  •  0
  •   DrKey    7 年前

    我想我找到了我想要的答案。

    通过条令类进行调试(特别是 UnitOfWork::createEntity() )我发现条令不会覆盖现有的实体数据,除非查询明确指定 Query::HINT_REFRESH 提示:

    $result = $this->getEntityManager()->createQueryBuilder()
        ->select('e')
        ->from(MyEntity::class, 'e')
        ->getQuery()->setHint(Query::HINT_REFRESH, true)->getResult();
    

    这样,即使实体已经加载到内存中,如果有新的数据库数据可供该实体使用,则条令也会覆盖实体属性。此外,这并不会像 $em->refresh() 做。

    事实上,这也得到了 official documentation :

    查询::提示\u刷新-此查询由内部使用 EntityManager::Refresh(),也可以在Userland中使用。如果你 指定此提示,查询将返回以下实体的数据: 已由UnitOfWork管理,即现有实体的字段 将刷新。在正常操作中,加载 已存在的实体将被放弃,取而代之的是 现有实体。