Dzi*_*mid 2 serialization symfony doctrine-orm deserialization
我正在使用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;
}
Run Code Online (Sandbox Code Playgroud)
映射到此json:{"id":1,"items":[{"id":1,"amount":100}, {"id":2,"amount":200}]}并将相同的json正确反序列化为MyBundle类型的对象:具有两个MyBundle:Order/Item对象的集合.
问题是,当我尝试持久保存此对象时,会在数据库中创建新条目,而不是更新现有条目,忽略ID.我如何告诉实体经理这些对象应该更新,而不是创建?
更新.通常,EntityManager :: merge解决方案(由DaveM建议)很好.但您必须只合并现有对象.例如,如果您有一个json,它表示连接到现有Order\Item实体的新Order实体
{"id":null,"items":[{"id":1,"金额":100},{"id":2,"金额":200}]}
在这种情况下,你不能像这样合并一个Order对象:
$em->merge($order),因为order是一个新实体,而实体管理器将尝试找到一个id = null的Order对象,你将得到一个新的Order和empty items数组.所以解决方案是循环Order :: $ items数组并单独合并每个项目.然后将创建一个新订单并与现有项目连接.
您需要merge()在EntityManager合并实体上使用该方法,这是指将实体合并到EntityManager的上下文中,以便它们可以再次被管理.为了将实体的状态合并到EntityManager中,请使用EntityManager#merge($ entity)方法.传递的实体的状态将合并到此实体的托管副本中,随后将返回此副本.
$detachedEntity = unserialize($serializedEntity);
$entity = $em->merge($detachedEntity);
Run Code Online (Sandbox Code Playgroud)
另外一定要注意,当您要序列化/反序列化实体时,您必须使所有实体属性受到保护,而不是私有.这样做的原因是,如果您之前序列化一个代理实例的类,则不会序列化私有变量并抛出PHP Notice.
更多信息可以在这里的学说文档中找到:
http://doctrine-orm.readthedocs.org/en/2.0.x/reference/working-with-objects.html#merging-entities
| 归档时间: |
|
| 查看次数: |
6314 次 |
| 最近记录: |