gpt4 book ai didi

php - Symfony 与教义 : UnitOfWork undefined index after calling flush()

转载 作者:行者123 更新时间:2023-12-03 14:39:43 26 4
gpt4 key购买 nike

我有 3 个实体:

文件夹 :

<?php
namespace CMS\ExtranetBundle\Entity;

use Doctrine\ORM\Mapping as ORM;

/**
* Folder
*
* @ORM\Table(name="folder")
* @ORM\HasLifecycleCallbacks
* @ORM\Entity(repositoryClass="CMS\ExtranetBundle\Repository\FolderRepository")
*/
class Folder
{
/**
* @ORM\Id
* @ORM\Column(name="id", type="guid")
* @ORM\GeneratedValue(strategy="UUID")
*/
public $id;
// Used in NotificationListener
public $beforeRemoveId;
/**
* @ORM\OneToMany(targetEntity="Document", mappedBy="folder", cascade={"persist", "remove"})
*/
public $documents;
}

文档 :
<?php
namespace CMS\ExtranetBundle\Entity;

use Doctrine\ORM\Mapping as ORM;

/**
* Document
* @ORM\Entity(repositoryClass="CMS\ExtranetBundle\Repository\DocumentRepository")
* @ORM\Table(name="document")
* @ORM\HasLifecycleCallbacks
*/
class Document
{
/**
* @ORM\Id
* @ORM\Column(name="id", type="guid")
* @ORM\GeneratedValue(strategy="UUID")
*/
public $id;
/**
* @ORM\ManyToOne(targetEntity="Folder", inversedBy="documents", cascade={"persist"})
* @ORM\JoinColumn(name="folder_id", referencedColumnName="id", nullable=true)
*/
public $folder;
}

和通知:
<?php
namespace CMS\ExtranetBundle\Entity;

use Doctrine\ORM\Mapping as ORM;

/**
* @ORM\Table(name="notification")
* @ORM\Entity(repositoryClass="CMS\ExtranetBundle\Repository\NotificationRepository")
* @ORM\HasLifecycleCallbacks
*/
class Notification
{
/**
* @ORM\Id
* @ORM\Column(name="id", type="guid")
* @ORM\GeneratedValue(strategy="UUID")
*/
public $id;
/**
* @ORM\ManyToOne(targetEntity="User", inversedBy="notifications", cascade={"persist"})
* @ORM\JoinColumn(name="user_id", referencedColumnName="id", nullable=true, onDelete="CASCADE")
*/
public $user;
/**
* @ORM\Column(name="type", type="string", length=16)
*/
public $type;
/**
* @ORM\Column(name="object_id", type="string", length=36)
*/
public $objectId;
}

最后,我有一个监听器,而不是“监听”“文档”实体(preRemove 和 postRemove)以删除通知实体。通知实体不通过关系链接到文档,因为字段“objectId”是通用的,它可以包含其他实体,具体取决于“type”属性。

这是我的听众:
<?php
namespace CMS\ExtranetBundle\EventListener;

use Doctrine\ORM\Event\LifecycleEventArgs;

class NotificationListener
{
/**
* Enregistre l'ID avant la suppression pour l'utiliser dans le postRemove
*
* @param LifecycleEventArgs $args
* @return bool|void
*/
public function preRemove(LifecycleEventArgs $args)
{
$entity = $args->getEntity();
$class = (new \ReflectionClass($entity))->getShortName();
if (!$this->isOfValidClass($class)) {
return;
}
$entity->beforeRemoveId = $entity->getId();
}
/**
* Lors de la suppression d'une entité, supprime les notifications correspondantes.
*
* @param LifecycleEventArgs $args
* @return bool|void
*/
public function postRemove(LifecycleEventArgs $args)
{
$entity = $args->getEntity();
$class = (new \ReflectionClass($entity))->getShortName();
if (!$this->isOfValidClass($class)) {
return;
}
$id = $entity->beforeRemoveId;
if (!$id) {
return;
}

$em = $args->getEntityManager();
$notifications = $em->getRepository('CMSExtranetBundle:Notification')->findBy([
'type' => strtolower($class),
'objectId' => $id
]);
if (count($notifications)) {
$batchSize = 20;
$i = 1;
foreach ($notifications as $notification) {
$em->remove($notification);
if (($i % $batchSize) === 0) {
$em->flush();
$em->clear();
}
++$i;
}
// It fails after calling flush()
$em->flush();
}
}
private function isOfValidClass($class)
{
$allowedClasssNames = [
'Document',
];
foreach ($allowedClasssNames as $allowedClasssName) {
if ($class == $allowedClasssName) {
return true;
}
}
return false;
}
}

我正在尝试删除包含多个文档的文件夹实体。

这是我的 Controller :
<?php
namespace CMS\ExtranetBundle\Controller;

use Symfony\Component\HttpFoundation\JsonResponse;
use CMS\ExtranetBundle\Entity\Folder;
use CMS\ExtranetBundle\Security\Voters\FolderVoter;

class FolderController extends DefaultController
{
public function deleteAction(Request $request, Folder $folder)
{
// Authorization
$this->denyAccessUnlessGranted(FolderVoter::WRITE, $folder);
$em = $this->getDoctrine()->getManager();
$em->remove($folder);
$em->flush();
return new JsonResponse([
'status' => true,
]);
}
}

我的问题是,有时,当我删除一个文件夹,其中包含文档,有通知,我收到这个错误:

enter image description here

(NotificationListener.php 的第 73 行对应 postRemove 循环后的最后一个 $em->flush();)

如果文档没有通知,则它有效

任何的想法 ?

最佳答案

好的,感谢 irc.freenode.net 上的 srm`@#symfony-fr,我改变了删除通知的方式。这是我的 NotificationListener 的 postRemove() 方法:

/**
* Lors de la suppression d'une entité, supprime les notifications correspondantes.
*
* @param LifecycleEventArgs $args
* @return bool|void
*/
public function postRemove(LifecycleEventArgs $args)
{
$entity = $args->getEntity();

// Récupère le nom 'court' de la classe
$class = (new \ReflectionClass($entity))->getShortName();

if (!$this->isValidClass($class)) {
return;
}
$id = $entity->beforeRemoveId;
if (!$id) {
return;
}
$em = $args->getEntityManager();

$queryBuilder = $em
->createQueryBuilder()
->delete('CMSExtranetBundle:Notification', 'n')
->where('n.type = :type')
->andWhere('n.objectId = :objectIds')
->setParameter(':type', strtolower($class))
->setParameter(':objectIds', $entity->beforeRemoveId);

$queryBuilder->getQuery()->execute();

}

谢谢 ! :-D

关于php - Symfony 与教义 : UnitOfWork undefined index after calling flush(),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44945366/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com