JMS反序列化对象中的数组集合


JMS Deserialize ArrayCollection in Object

我试图在我的应用程序中使用JMS序列化器(不是Symfony),并希望将JSON对象反序列化到Doctrine Entity。
普通属性得到了正确的反序列化,但我不能让数组集合工作。

这是我的产品JSON的摘录:

{
  "id": 2,
  "name": "Shirt blue",
  "attributeValues": [
    {
      "id": 4,
      "title": "S",
      "attributeId": 2
    },
    {
      "id": 7,
      "title": "Eterna",
      "attributeId": 3
    }
  ]
}

这是我的Product实体:

<?php
namespace Vendor'App'Common'Entities;
use Doctrine'Common'Collections'ArrayCollection;
use Doctrine'ORM'Mapping as ORM;
use JMS'Serializer'Annotation as JMS;
/**
 * @ORM'Entity
 * @ORM'HasLifecycleCallbacks
 * @ORM'Table(name="product")
 * @JMS'ExclusionPolicy("all")
 */
class Product extends AbstractEntity {
    /**
     * @var int $id
     * @ORM'Id
     * @ORM'GeneratedValue(strategy="IDENTITY")
     * @ORM'Column(name="id", type="integer", nullable=false)
     * @JMS'Groups({"search"})
     * @JMS'Expose
     * @JMS'Type("integer")
     */
    protected $id;
    /**
     * @var string $name
     * @ORM'Column(name="name", type="string", nullable=false)
     * @JMS'Expose
     * @JMS'Groups({"search"})
     * @JMS'Type("string")
     */
    protected $name;
    /**
     * @var ArrayCollection $attributeValues
     * @ORM'ManyToMany(targetEntity="Vendor'App'Common'Entities'Attribute'Value")
     * @ORM'JoinTable(name="products_values",
    *      joinColumns={@ORM'JoinColumn(name="product_id", referencedColumnName="id")},
    *      inverseJoinColumns={@ORM'JoinColumn(name="value_id", referencedColumnName="id")}
     *      )
     * @JMS'Expose
     * @JMS'MaxDepth(2)
     * @JMS'Groups({"search"})
     * @JMS'Type("ArrayCollection<Vendor'App'Common'Entities'Attribute'Value>")
     */
    protected $attributeValues;
    public function __construct() {
        $this->attributeValues = new ArrayCollection();
    }
    /**
     * @return ArrayCollection
     */
    public function getAttributeValues() {
        return $this->attributeValues;
    }
    /**
     * @param ArrayCollection $attributeValues
     */
    public function setAttributeValues($attributeValues) {
        $this->attributeValues = $attributeValues;
    }
    /**
     * @param Value $attributeValue
     */
    public function addAttributeValue($attributeValue) {
        $this->attributeValues->add($attributeValue);
    }
    /**
     * @param Value $attributeValue
     */
    public function removeAttributeValue($attributeValue) {
        $this->attributeValues->removeElement($attributeValue);
    }
}

这是我的值实体,应该在ArrayCollection中反序列化:

<?php
namespace Vendor'App'Common'Entities'Attribute;
use Vendor'App'Common'Entities'AbstractEntity,
    Doctrine'ORM'Mapping as ORM,
    JMS'Serializer'Annotation as JMS;
/**
 * @ORM'Entity
 * @ORM'Table(name="attribute_value")
 * @JMS'ExclusionPolicy("all")
 */
class Value extends AbstractEntity {
    /**
     * @var int $id
     * @ORM'Id
     * @ORM'GeneratedValue(strategy="IDENTITY")
     * @ORM'Column(name="id", type="integer", nullable=false)
     * @JMS'Expose
     * @JMS'Groups({"search"})
     * @JMS'Type("integer")
     */
    protected $id;
    /**
     * @var string $title
     * @ORM'Column(name="title", type="string", nullable=false)
     * @JMS'Expose
     * @JMS'Groups({"search"})
     * @JMS'Type("string")
     */
    protected $title;
    /**
     * @var int $attributeId
     * @ORM'Column(name="attribute_id", type="integer", nullable=false)
     * @JMS'Expose
     * @JMS'Groups({"search"})
     * @JMS'Type("integer")
     */
    protected $attributeId;
    /**
     * OWNING SIDE
     * @var 'Vendor'App'Common'Entities'Attribute $attribute
     * @ORM'ManyToOne(targetEntity="Vendor'App'Common'Entities'Attribute", inversedBy="values")
     * @ORM'JoinColumn(name="attribute_id", referencedColumnName="id")
     * @JMS'Expose
     * @JMS'Groups({"search"})
     * @JMS'Type("Vendor'App'Common'Entities'Attribute")
     */
    protected $attribute;
    //Getters and setters ...
}

只是试图简单地反序列化实体:

$serializer = SerializerBuilder::create()->build();
$entity = $serializer->deserialize($sourceJson, Product::class, 'json');

但是attributeValue ArrayCollection仍然为空。我错过了什么?

我找到了解决方案。JMS有一个默认的命名策略,将驼峰大小写转换为下划线表示法。默认情况下,命名策略查找注释@SerializedName,如果没有设置,则将CamelCase转换为下划线。

这个属性被忽略了,因为它和预期的名字不匹配。当然,如果在这里有一个错误或提示在哪里搜索问题的通知(像未知属性这样的东西会更好)。

$serializer = SerializerBuilder::create()->setPropertyNamingStrategy(new IdenticalPropertyNamingStrategy())->build();

是解决方案