сохраненная доктрина сущность изменена между entityManager-> persist и unitOfWork-> persist

В моем приложении symfony2 / doctrine2 у меня есть странный случай, когда при сохранении измененного объекта изменение не сбрасывается в базу данных, и я не могу понять, почему.

Ниже мой код:

$date = $subscription->getPaymentValidUntil()->format('d/m/Y');
$period = $payment->getDetail('period');
$validDate = $subscription->getPaymentValidUntil()
->add(new\DateInterval($period == Subscription::MONTH ? 'P1M' : 'P1Y'))
;

$subscription->setPaymentValidUntil($validDate);
$this->em->persist($subscription);

exit(var_dump(array(
$date,
$this->em->getUnitOfWork()->getScheduledEntityUpdates(),
$subscription->getPaymentValidUntil(),
)));

$this->em->flush();

Вывод vardump следующий:

array (size=3)
0 => string '12/05/2015' (length=10)
1 =>
array (size=0)
empty
2 =>
object(DateTime)[2295]
public 'date' => string '2015-06-12 18:52:37' (length=19)
public 'timezone_type' => int 3
public 'timezone' => string 'Europe/Paris' (length=12)

Если я сбрасываю данные перед vardump или удаляю vardump, действительно, значение даты не изменяется в моей базе данных. Зачем?

Как видите, я добавляю один месяц к этому значению даты, это отражается на объекте, но не запланировано для обновления. Как я могу решить это?

РЕДАКТИРОВАТЬ: Я копался в функции персистента диспетчера сущностей, и я понял, что при выгрузке сущности в Doctrine \ ORM \ EntityManager :: persist дата была хорошей, но при выгрузке ее в Doctrine \ ORM \ UnitOfWork :: persist, дата был каким-то образом сброшен к первоначальному:

Doctrine\ORM\EntityManager::persist : выдает обновленную сущность

public function persist($entity)
{
if ( ! is_object($entity)) {
throw ORMInvalidArgumentException::invalidObject('EntityManager#persist()' , $entity);
}

$this->errorIfClosed();

if ($entity instanceof Subscription) exit(var_dump($entity));

$this->unitOfWork->persist($entity);
}

Doctrine \ ORM \ UnitOfWork :: persist: выводит неизмененную сущность: ПОЧЕМУ?

private function doPersist($entity, array &$visited)
{
if ($entity instanceof Subscription) exit(var_dump($entity));

$oid = spl_object_hash($entity);

if (isset($visited[$oid])) {
return; // Prevent infinite recursion
}
}

5

Решение

DateTime являются объектом в конце концов, и всегда передаются по ссылке. Итак, я настоятельно рекомендую вам отредактировать ваш код следующим образом:

$period = $payment->getDetail('period');
$validDate = clone $subscription->getPaymentValidUntil();
$validDate->add(new \DateInterval($period == Subscription::MONTH ? 'P1M' : 'P1Y'));
$subscription->setPaymentValidUntil($validDate);
$this->em->persist($subscription);
$this->em->flush();

Таким образом, вы гарантируете, что вы передаете объект другому объекту, и избегаете каких-либо незначительных ошибок в EntityManager.

4

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]