Чтобы все было просто, у меня есть
/*
* @JMS\Discriminator(field = "type", map = {
* "one": "...\ItemOne",
* "two": "...\ItemTwo"
* })
*/
Abstract Class Item {}
.
.
.
class ItemOne extends Item {/* Contains multiple properties */}
class ItemTwo extends Item {/* Contains multiple properties */}
class Example
{
/**
* @var Item[] $items
*
* @ORM\OneToMany(targetEntity="...\Items", mappedBy="holder",cascade={"persist", "remove"})
*/
protected $items;
}
Как только я сериализую этот объект с помощью FOSRestBundle, все выглядит хорошо, я получаю массив элементов, и каждый элемент будет иметь поле дискриминатора, но после десериализации я получаю следующую ошибку
"You must define a type for ...\Example::$items."
Итак, чтобы решить эту проблему, я добавил
/**
* @ORM\...
* @JMS\Type("ArrayCollection<...\Item>")
*/
protected $items;
На этот раз сериализованный $items
, похоже, ограничен родительским классом Item
, все объекты потеряют все свойства, связанные с дочерними элементами ItemOne
и ItemTwo
, и будут сериализованы без какого-либо поля дискриминатора, поэтому десерализация завершится ошибкой.
"The discriminator field name "type" for base-class "...\Item" was not found in input data."
Как я могу решить эту проблему?
ИЗМЕНИТЬ, поскольку @erlangb предположил, что это распространенная проблема в JMS Serializer
https://github.com/schmittjoh/JMSSerializerBundle/issues/292
хотя я не смог заставить это работать, используя упомянутый обходной путь
/**
* @JMS\Discriminator(field = "type", map = {"car": "...\Test\Car", "moped":"...\Test\Moped"})
*/
abstract class Vehicle {
public $id;
}
class Car extends Vehicle {
/**
*@JMS\Type("integer")
*/
public $id;
/**
*@JMS\Type("string")
*/
public $car_at;
/**
* @JMS\VirtualProperty
*/
public function getType()
{
return 'car';
}
}
class Moped extends Vehicle {
/**
*@JMS\Type("integer")
*/
public $id;
/**
*@JMS\Type("string")
*/
public $moped_at;
/**
* @JMS\VirtualProperty
*/
public function getType()
{
return 'moped';
}
}
class Saloon
{
/**
*@JMS\Type("integer")
*/
public $id;
/**
* @JMS\Type("...\Test\Vehicle")
*/
public $veichle;
}
//In controller
$car = new Car();
$car->id = 1;
$car->car_at = "car";
$car2 = new Moped();
$car2->id = 2;
$car2->moped_at = "moped";
$saloon = new Saloon();
$saloon->veichle = $car2;
$json = $this->get('jms_serializer')->serialize($saloon,'json');
$saloon_des = $this->get('jms_serializer')->deserialize($json,'...\Saloon','json');
все еще получаю
The discriminator field name "type" for base-class "...\Test\Vehicle" was not found in input data.
или если я удалю @JMS\Type
из Saloon->veichle
, я получу
The discriminator field name "type" of the base-class "...\Test\Vehicle" conflicts with a regular property of the sub-class "...\Test\Moped".
scasei
на github создал патч, но у меня еще не было времени его протестировать. Подробнее об этой проблеме можно прочитать здесь: github.com/schmittjoh/JMSSerializerBundle/issues/292 а> - person trrrrrrm   schedule 08.08.2014