如何在 Doctrine 3 中替换 EntityManager::merge? [英] How to replace EntityManager::merge in Doctrine 3?

查看:29
本文介绍了如何在 Doctrine 3 中替换 EntityManager::merge?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在开发一个基于 Symfony 2.8 的网络应用项目,该项目目前使用 Doctrine 2.该项目基本上是一个简单的待办事项列表应用程序,可以与移动应用程序(iOS/Android)同步.

在阅读 Doctrine 3 的更新说明时,我发现 EntityManager::merge 将不再受支持.

<块引用>

ORM 3.0 没有提供 EntityManager#merge() 的替代方法,因为合并语义应该是业务领域的一部分而不是应用程序的持久域.如果你的应用程序严重依赖于类似 CRUD 的交互和/或 PATCH宁静的操作,你应该看看替代品,比如JMSSerializer.

我不确定替换 EntityManager::merge 的最佳/正确方法是什么?

我在哪里使用合并:

在移动应用程序与 Web 应用程序同步期间,数据作为序列化 JSON 传输,然后由 JMSSerializer 反序列化到实体对象.当 Web 应用程序以这种方式接收 ToDoEntry 对象时,它可以是一个新的 ToDo-Entry(在 Web 应用程序中尚不知道)或更新的现有条目.无论哪种方式,接收到的对象都不是由 EntityManager 管理的.因此 $em->persist($receivedObject) 将始终尝试插入一个新对象.如果 Web 应用程序中已经存在 ToDo-Entry 并且需要更新,这将失败(由于 id 的唯一约束).

取而代之的是 $em->merge($receivedObject) 用于自动检查是否需要插入或更新.

我能解决这个问题吗?

当然,如果已经存在具有相同 ID 的实体,我可以检查每个接收到的对象.在这种情况下,可以加载现有对象并手动更新其属性.然而,这将是非常麻烦的.真正的项目当然使用许多不同的实体,每个实体类型/类都需要自己的处理来检查哪些属性需要更新.没有更好的解决方案吗?

解决方案

可以尝试使用 Doctrine\ORM\UnitOfWork 的 registerManaged() 方法.

//$this->em <--- Doctrine 实体管理器//$entity <--- 分离的实体(例如我们知道这个实体已经存在于数据库中)$id = [$entity->getId()];//大批$data = $entity->toArray();//大批$this->em->getUnitOfWork()->registerManaged($entity, $id, $data);

当然,您可以在执行所需操作之前/之后使用 Doctrine\ORM\UnitOfWork 的 getEntityState() 检查您的实体的状态.

$this->eM->getUnitOfWork()->getEntityState($entity, $assert = 3)

<块引用>

$assert <-- 如果 NEW 和 DETACHED 之间的区别已知或对方法的调用者无关紧要,则可以设置此参数以通过潜在地避免数据库查找来提高实体状态检测的性能.

I am working an Symfony 2.8 based web app project which currently uses Doctrine 2. The project is basically a simple ToDo list application which can be synced with a mobile app (iOS/Android).

While reading the Update notes of Doctrine 3 I discovered, that EntityManager::merge will no longer be supported.

An alternative to EntityManager#merge() is not provided by ORM 3.0, since the merging semantics should be part of the business domain rather than the persistence domain of an application. If your application relies heavily on CRUD-alike interactions and/or PATCH restful operations, you should look at alternatives such as JMSSerializer.

I am not sure what is the best/correct way to replace EntityManager::merge?

Where do I use merge:

During the sync of the mobile apps with the web app the data is transferred as serialized JSON which is than de-serialized by JMSSerializer to an entity object. When the web app receives a ToDoEntry object this way, it can be a new ToDo-Entry (not known in the web app yet) or an updated existing entry. Either way, the received object is not managed by the EntityManager. Thus $em->persist($receivedObject) will always try to insert a new object. This will fail (due to the unique constraint of the id) if the ToDo-Entry already exists in the web app and needs to be updated.

Instead $em->merge($receivedObject) is used which automatically checks wether an insert or update is required.

Hot wo solve this?

Of course I could check for every received objects if an entity with the same ID already exists. In this case could load the existing object and update its properties manually. However this would be very cumbersome. The real project of course uses many different entities and each entity type/class would need its own handling to check which properties needs to be updated. Isn't there a better solution?

解决方案

You can try to use registerManaged() method of Doctrine\ORM\UnitOfWork.

// $this->em <--- Doctrine Entity Manager
// $entity <--- detached Entity (and we know that this entity already exists in DB for example)

$id = [$entity->getId()]; //array
$data = $entity->toArray(); //array

$this->em->getUnitOfWork()->registerManaged($entity, $id, $data);

Of course, You can check the state of Your Entity using getEntityState() of Doctrine\ORM\UnitOfWork before/after perfoming needed actions.

$this->eM->getUnitOfWork()->getEntityState($entity, $assert = 3)

$assert <-- This parameter can be set to improve performance of entity state detection by potentially avoiding a database lookup if the distinction between NEW and DETACHED is either known or does not matter for the caller of the method.

这篇关于如何在 Doctrine 3 中替换 EntityManager::merge?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆