相关疑难解决方法(0)

如何从@Groups包含策略更新symfony2/doctrine实体JMSSerializer反序列化实体

我正在尝试使用带有@ExclusionPolicy的JMSSerializer来更新symfony2/doctrine实体:无@Groups包含策略.

 * @Serializer\ExclusionPolicy("none")
 */
 class Foo
 {
    /**
     * @Serializer\Groups({"flag","edit"})
     */
    protected $id;

    /**
     * @Serializer\Groups({"edit"})
     */
    protected $name;

    /**
     * @Serializer\Groups({"flag"})
     */
    protected $flag;

    /**
     * @Serializer\Exclude()
     */
    protected $createdBy;
 }
Run Code Online (Sandbox Code Playgroud)

参考:http://jmsyst.com/libs/serializer/master/reference/annotations

以下记录的结果:

Foo (id:1, name:'bar', flagged:false ,created_by:123)
Run Code Online (Sandbox Code Playgroud)

使用Group包含序列化以避免序列化我不需要的信息(关联,blob等等)所以当我想更新实体时,我只从JSON反序列化实体的更新字段.

$foo->setFlagged(true);
$data = $serializer->serialize($foo, 'json', SerializationContext::create()->setGroups(array("flag")));

result:
{id:1,flagged:true}
Run Code Online (Sandbox Code Playgroud)

传递回应用程序时反序列化为实体

$foo = $serializer->deserialize($jsonFoo,'Foo','json');

result:
Foo (id:1, name:null, flagged:true, created_by:null)
Run Code Online (Sandbox Code Playgroud)

问题是当我尝试将实体合并回到主题实体管理器时:

$foo = $em->merge($foo);
$em->persist($foo);
$em->flush();
Run Code Online (Sandbox Code Playgroud)

生成的foo尝试使用null更新排除的属性(name,created_by).

如何告诉JMSSerializer或Doctrine Entity Manager合并我不想用null覆盖现有属性?

symfony doctrine-orm jmsserializerbundle

11
推荐指数
1
解决办法
5506
查看次数

如何从序列化的JSON更新Doctrine实体?

我们正在使用Symfony2来创建API.更新记录时,我们希望JSON输入表示序列化更新的实体.JSON数据将不包含某些字段(例如,创建实体时,CreatedAt只应设置一次 - 并且永远不会更新).例如,这是一个示例JSON PUT请求:

{"id":"1","name":"anyname","description":"anydescription"}
Run Code Online (Sandbox Code Playgroud)

这是Controller上的PHP代码,它应该根据上面的JSON更新实体(我们使用的是JMS序列化器Bundle):

$supplier = $serializer->deserialize(
    $this->get('request')->getContent(),
    'WhateverEntity',
    'json'
);
Run Code Online (Sandbox Code Playgroud)

EntityManger(正确地)理解这是一个更新请求(实际上,隐式触发了SELECT查询).EntityManager还猜测(不正确)CreatedAt属性应该被NULL化 - 它应该保留前一个属性.

如何解决这个问题?

symfony doctrine-orm

8
推荐指数
3
解决办法
8007
查看次数

如何使用实体管理器管理反序列化的实体?

我正在使用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数组并单独合并每个项目.然后将创建一个新订单并与现有项目连接.

serialization symfony doctrine-orm deserialization

2
推荐指数
1
解决办法
6314
查看次数