Я пытаюсь записать каждое изменение количества данного товара.Для этого я ожидаю изменения сущности Item и хочу создать новый экземпляр Transaction с подробными сведениями о действии.Итак, я создаю сущность внутри слушателя.
Я настроил все в соответствии с документацией и создал слушателя на основе этого примера.
Код (я считаю) имеет отношение к моей проблеме следующим образом.
ItemListener
// ...
private $log;
/** @ORM\PreUpdate */
public function preUpdateHandler (Item $item, PreUpdateEventArgs $args)
{
$changeSet = $args->getEntityManager()->getUnitOfWork()->getEntityChangeSet($item)['quantity'];
$quantityChange = $changeSet[1] - $changeSet[0];
$transaction = new Transaction();
$transaction->setItem($item);
$transaction->setQuantityChange($quantityChange);
$this->log = $transaction;
}
/** @ORM\PostUpdate */
public function postUpdateHandler(Item $item, LifecycleEventArgs $args)
{
$em = $args->getEntityManager();
$em->persist($this->log);
$em->flush();
}
Это работает отлично.Однако проблема заключается в том, что я добавляю еще одно поле в объект транзакции.Поле user внутри Transaction имеет отношение ManyToOne.Теперь, когда я пытаюсь установить пользователя внутри preUpdateHandler
, это приводит к неопределенной ошибке индекса внутри функции UnitOfWork
в Entity Manager.
Notice: Undefined index: 000000003495bf92000000001108e474
Слушатель теперь такой.Я получаю пользователя на основе токена, который был отправлен с запросом.Поэтому я вставляю стек запросов и мой пользовательский провайдер в конструктор слушателя.Я не думаю, что это является источником проблемы.Однако, если необходимо, я отредактирую сообщение и добавлю весь оставшийся код (оставшаяся часть слушателя, services.yaml и провайдера пользователя).
ItemListener
// ...
private $log;
/** @ORM\PreUpdate */
public function preUpdateHandler (Item $item, PreUpdateEventArgs $args)
{
$changeSet = $args->getEntityManager()->getUnitOfWork()->getEntityChangeSet($item)['quantity'];
$quantityChange = $changeSet[1] - $changeSet[0];
$transaction = new Transaction();
$transaction->setItem($item);
$transaction->setQuantityChange($quantityChange);
$request = $this->requestStack->getCurrentRequest();
$company = $this->userProvider->getUserByRequest($request);
$this->log = $transaction;
}
/** @ORM\PostUpdate */
public function postUpdateHandler(Item $item, LifecycleEventArgs $args)
{
$em = $args->getEntityManager();
$em->persist($this->log);
$em->flush();
}
Я не понимаю, почему получение сброса с извлечением другого объекта приводит к этой ошибке.При поиске ответа я обнаружил, что многие рекомендуют не использовать flush()
в цикле postUpdate
, а в postFlush
.Однако этот метод не определен для прослушивателей Entity в соответствии с документацией, и, если возможно, я бы хотел придерживаться такого прослушивателя, а не прослушивателя событий.
Спасибо за любую помощь.Я также включаю код объекта транзакции на всякий случай.
Объект транзакции
<?php
namespace App\Entity;
use Doctrine\ORM\Mapping as ORM;
use App\DoctrineUtils\MagicAccessors;
use App\Entity\T\TIdentifier;
/**
* @ORM\Entity
* @ORM\Table(name="transaction")
*/
class Transaction
{
use TIdentifier;
use MagicAccessors;
/**
* @ORM\ManyToOne(targetEntity="Item")
* @ORM\JoinColumn(name="item_id", referencedColumnName="id", nullable=false)
*/
public $item;
/**
* @ORM\Column(type="decimal", length=14, precision=4, nullable=false)
*/
public $quantityChange;
/**
* @ORM\Column(type="datetime", nullable=true)
*/
private $createdTime;
/**
* @ORM\ManyToOne(targetEntity="App\Entity\User")
* @ORM\JoinColumn(nullable=false)
*/
private $user;
public function __construct()
{
$this->createdTime = new \DateTime();
}
/**
* @param mixed $quantityChange
*/
public function setQuantityChange(int $quantityChange): void
{
$this->quantityChange = $quantityChange;
}
/**
* @param mixed $createdTime
*/
public function setCreatedTime($createdTime): void
{
$this->createdTime = $createdTime;
}
/** @ORM\PrePersist **/
public function onCreate() : void
{
$this->setCreatedTime(new \DateTime('now'));
}
public function setUser(?User $user): self
{
$this->user= $user;
return $this;
}
}