我在Symfony3项目中有一个postFlush
事件订阅者/侦听器,它从集合中检查数据库中的现有项目,如果找到匹配项,它会将现有实体重新分配给Document
和使用orphanRemoval=true
删除新的。该代码适用于Tag
但是当我尝试使用继承映射Tool
对实体执行相同操作时,我收到错误:
Warning: Invalid argument supplied for foreach()
------------------------------------------------
in vendor/doctrine/orm/lib/Doctrine/ORM/Persisters/Entity/BasicEntityPersister.php at line 526
foreach ($joinColumns as $joinColumn) {
$keys[] = $this->quoteStrategy->getJoinColumnName($joinColumn, $class, $this->platform);
}
我有一个Tool
和一个Part
,它们共享一个公共表格/结构Equipment
,与ManyToMany
的{{1}}关系。它们共享一个公共结构,并使用带有Document
字段的SINGLE_TABLE继承。
我的discr
实体:
Document
我的小/**
* @ORM\Entity
*/
class Document
{
/**
* @ORM\Column(type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
*
* @var integer
*/
private $id;
/**
* @ORM\Column(type="string", nullable=false)
*
* @var string
*/
private $title;
/**
* @ORM\ManyToMany(targetEntity="Tag", inversedBy="documents", cascade={"persist"}, orphanRemoval=true)
* @ORM\JoinTable(name="document_tags")
*
* @var Collection
*/
private $tags;
/**
* @ORM\ManyToMany(targetEntity="Tool", inversedBy="documents", cascade={"persist"}, orphanRemoval=true)
* @ORM\JoinTable(name="document_tools")
*
* @var Collection
*/
private $tools;
}
实体:
Tool
/**
* @ORM\Entity
*/
class Tool extends Equipment {}
抽象实体:
Equipment
这是听众代码:
/**
* @ORM\Entity
* @ORM\Table(name="equipment")
* @ORM\InheritanceType("SINGLE_TABLE")
* @ORM\DiscriminatorColumn(name="discr", type="string")
* @ORM\DiscriminatorMap({"tool" = "Tool", "part" = "Part"})
*/
abstract class Equipment
{
/**
* @ORM\Column(type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
*
* @var integer
*/
private $id;
/**
* @ORM\Column(type="string", nullable=false)
*
* @var string
*/
private $title;
/**
* @ORM\Column(type="string", nullable=true)
*
* @var string
*/
private $partNumber;
/**
* @ORM\ManyToMany(targetEntity="KBS\Entity\Document\Document", mappedBy="equipment")
*
* @var Collection
*/
private $documents;
}
当我们尝试删除孤立class DocumentListener implements EventSubscriber
{
/**
* @var array
*/
private $documents;
/**
* @param OnFlushEventArgs $event
*/
public function onFlush(OnFlushEventArgs $event)
{
$this->documents = [];
$em = $event->getEntityManager();
$uow = $em->getUnitOfWork();
foreach ($uow->getScheduledEntityUpdates() as $entity) {
if ($entity instanceof Document) {
$this->documents[] = $entity;
}
}
foreach ($uow->getScheduledEntityInsertions() as $entity) {
if ($entity instanceof Document) {
$this->documents[] = $entity;
}
}
}
/**
* @param PostFlushEventArgs $event
*/
public function postFlush(PostFlushEventArgs $event)
{
$em = $event->getEntityManager();
if (!empty($this->documents)) {
foreach ($this->documents as $document) {
$this->removeTagDuplicates($em, $document);
$this->removeToolDuplicates($em, $document);
}
$this->documents = [];
$em->flush();
}
}
/**
* @param EntityManager $em
* @param Document $document
*/
private function removeTagDuplicates(EntityManager $em, Document $document): void
{
$repository = $em->getRepository(Tag::class);
foreach ($document->getTags() as $entity) {
$numExisting = count($repository->findByLower($entity->getTitle()));
/** @var Tag $firstMatch */
$firstMatch = $repository->findOneByLower($entity->getTitle());
if ($numExisting > 1 && $firstMatch->getChecksum() === $entity->getChecksum()) {
$document->removeTag($entity);
$document->addTag($firstMatch);
}
}
}
/**
* @param EntityManager $em
* @param Document $document
*/
private function removeToolDuplicates(EntityManager $em, Document $document): void
{
$repository = $em->getRepository(Tool::class);
foreach ($document->getTools() as $entity) {
$numExisting = count($repository->findByLower($entity->getTitle()));
/** @var Tool $firstMatch */
$firstMatch = $repository->findOneByLower($entity->getTitle());
if ($numExisting > 1 && $firstMatch->getChecksum() === $entity->getChecksum()) {
$document->removeTool($entity);
$document->addTool($firstMatch);
}
}
}
}
时,是否存在丢失映射的原因?