php - JMS 反序列化对象中的 ArrayCollection

标签 php serialization doctrine-orm jms-serializer

我正在尝试在我的应用程序中使用 JMS 序列化程序(不是 Symfony),并且希望将 JSON 对象反序列化为 Doctrine 实体。
普通属性已正确反序列化,但我无法让 ArrayCollections 工作。

这是我的产品 JSON 的摘录:

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

这是我的产品实体:

<?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);
    }

}

这是我的 Value 实体,应在 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();

这是解决方案。

关于php - JMS 反序列化对象中的 ArrayCollection,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30377303/

相关文章:

php - 使用php将整数分成3部分

php - 我可以在 HTML5 中创建自定义 HTML 标签吗?

php - 添加 Serialized 接口(interface)后,unserialize() 停止工作

c# - 如何序列化一切

c - 如何将struct作为数组传输?

doctrine - 新 Doctrine 2.3 中的 @AssociationOverride 和 @AttributeOverride

PHP 输出缓冲?最佳做法是什么?

php - 维基百科信息框需要正则表达式

php - 学说查询不同的相关实体

php - 使用 Symfony 2,Doctrine 在 SQL 数据库中保存数组?