JMS 反序列化对象中的 ArrayCollection
JMS Deserialize ArrayCollection in Object
我正在尝试在我的应用程序(不是 Symfony)中使用 JMS 序列化器,并且想将一个 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);
}
}
这是我的值实体,应该在 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 转换为下划线。
所以 属性 只是被忽略了,因为它与预期的名称不匹配。当然,如果有错误或通知在这里提示在哪里搜索问题会更好(比如 unknown 属性 就好了)。
$serializer = SerializerBuilder::create()->setPropertyNamingStrategy(new IdenticalPropertyNamingStrategy())->build();
是解决方案。
我正在尝试在我的应用程序(不是 Symfony)中使用 JMS 序列化器,并且想将一个 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);
}
}
这是我的值实体,应该在 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 转换为下划线。
所以 属性 只是被忽略了,因为它与预期的名称不匹配。当然,如果有错误或通知在这里提示在哪里搜索问题会更好(比如 unknown 属性 就好了)。
$serializer = SerializerBuilder::create()->setPropertyNamingStrategy(new IdenticalPropertyNamingStrategy())->build();
是解决方案。