Doctrine2 ORM Игнорировать отношения в слиянии

Я реализую REST API с помощью FOSRestBundle и столкнулся с проблемой модификации существующего объекта (PUT).

У меня есть класс Student с отношением ManyToOne

/**
 * @JMS\MaxDepth(2)
 * @ORM\ManyToOne(targetEntity="ClassRoom", inversedBy="students")
 * @ORM\JoinColumn(name="classroom_id", referencedColumnName="id")
 */
protected $classRoom;

При выполнении действия PUT я получаю только атрибуты значения, так как я не хочу, чтобы пользователь мог изменять отношения с помощью запроса на размещение. Это пример полученных данных.

{
"id": 3,
"name": "pelayo",
"second_name": "ramon",
"last_name": "fernandez",
"birthday": "1983-08-15T00:00:00+0200"
}

Данные десериализуются с помощью сериализатора JMS, который устанавливает для атрибута $classRoom значение null, поскольку он не нашел его в полученных данных.

При выполнении слияния

$student2 = $this->get('doctrine')->getManager()->merge($student);

Если student2 сохраняется, текущая связь с classRoom стирается из базы данных, поскольку слияние устанавливает связь с нулевой.

Этого поведения можно избежать, получив текущую classRoom и установив ее в десериализованный объект вручную перед слиянием, но это уродливо.

Есть ли способ указать доктрине игнорировать атрибут при слиянии с отсоединенным и заставить его всегда использовать сохраненное значение?


person Nodens    schedule 13.03.2014    source источник
comment
Наткнулся на это тоже, слияние диспетчера сущностей означает слияние-отсоединенных-сущностей-к-em, а не слияние-этих-данных-с-сущностью. Ваш десериализованный объект ранее не был отсоединен, поэтому, насколько я понимаю, он не находится в надлежащем состоянии для объединения. Вы, вероятно, должны объединить обновленные данные с недавно полученным объектом - это даже подготовит вас к реализации частичного обновления (метод PATCH)   -  person jkavalik    schedule 14.03.2014
comment
Проблема с объединением данных с выбранным объектом заключается в том, что это утомительный и подверженный ошибкам метод. Может быть, мне следует разработать аннотацию и службу, которая считывает ее значение, чтобы знать атрибуты ведьм для слияния.   -  person Nodens    schedule 14.03.2014
comment
Что ж, вы можете использовать Hydrator->extract(), array_merge() и Hydrator->Hydrator(), amybe с небольшим количеством array_filter и/или array_intersect_key, чтобы сохранить его в безопасности.   -  person jkavalik    schedule 14.03.2014


Ответы (1)


Слияние — не единственное решение.

JMSSerializerBundle включает конструктор объектов для сущностей Doctrine. Когда вы включаете этот конструктор, десериализованные объекты становятся управляемыми объектами, которые можно сохранять (с помощью $em->persist($student)). Единственные атрибуты, измененные в десериализованном объекте, — это те, которые упомянуты в JSON из запроса.

Вот вы можете включить его.

person franbenz    schedule 23.06.2016