我正在使用 JMSSerializerBundle 将我的实体序列化为 json 并将 json 反序列化为实体,但我认为这个问题适用于任何反序列化技术。
例如,此架构:
class Order
{
private $id;
/**
* @Serializer\Type("ArrayCollection<MyBundle\Entity\Order\Item>")
* @ORM\OneToMany(targetEntity="\MyBundle\Entity\Order\Item", mappedBy="order", cascade={"persist"})
*/
private $items;
}
class Item
{
private $id;
/**
* @ORM\ManyToOne(targetEntity="\MyBundle\Entity\Order", inversedBy="items")
*/
private $order;
/**
* @var integer $amount
* @Serializer\Type("integer")
* @ORM\Column(name="amount", type="integer")
*/
private $amount;
}
映射到这个 json:{"id":1,"items":[{"id":1,"amount":100}, {"id":2,"amount":200}]}
并且相同的 json 被正确反序列化为MyBundle:Order类型的对象,该对象具有两个MyBundle:Order/Item对象的集合。
问题是,当我尝试持久化此对象时,会在数据库中创建新条目,而不是更新现有条目,而忽略 id。我如何告诉实体管理器这些对象应该更新,而不是创建?
更新。通常 EntityManager::merge 解决方案(如 DaveM 建议的那样)很好。但您只能合并现有对象。例如,如果您有一个 json 表示一个新的 Order 实体,该实体连接到现有的 Order\Item 实体
{"id":null,"items":[{"id":1,"amount":100}, {"id":2,"amount":200}]}
在这种情况下,您不能像这样合并 Order 对象:
$em->merge($order)
因为 order 是一个新实体,并且实体管理器将尝试查找 id = null 的 Order 对象,您最终将得到一个新的 Order 和空 items 数组。所以解决方案是循环 Order::$items 数组并单独合并每个项目。然后将创建一个新订单并将其与现有项目连接。