gpt4 book ai didi

php - 如何在 onFlush 事件监听器中更新实体的 manyToMany 集合?

转载 作者:可可西里 更新时间:2023-11-01 14:04:24 26 4
gpt4 key购买 nike

我有这个实体:

<?php

namespace Comakai\MyBundle\Entity;

use Doctrine\ORM\Mapping as ORM,
Symfony\Component\Validator\Constraints as Assert;

/**
* @ORM\Entity
*/
class Stuff {

/**
* @ORM\Id
* @ORM\Column(type="integer")
* @ORM\GeneratedValue(strategy="IDENTITY")
*/
private $id;

/**
* @ORM\Column(type="text")
* @Assert\NotBlank()
*/
private $content;

/**
* @ORM\ManyToMany(targetEntity="Apple", cascade={"persist"})
*/
private $apples;

/**
* @ORM\ManyToMany(targetEntity="Pig")
*/
private $pigs;

public function __construct() {
$this->apples = new \Doctrine\Common\Collections\ArrayCollection();
$this->pigs = new \Doctrine\Common\Collections\ArrayCollection();
}

public function setApples($apples) {

$this->getApples()->clear();

foreach ($apples as $apple) {

$this->addApple($apple);
}
}

public function setPigs($pigs) {

$this->getPigs()->clear();

foreach ($pigs as $pig) {

$this->addPig($pig);
}
}

/**
* Get id
*
* @return integer
*/
public function getId() {
return $this->id;
}

/**
* Set content
*
* @param text $content
*/
public function setContent($content) {
$this->content = $content;
}

/**
* Get content
*
* @return text
*/
public function getContent() {
return $this->content;
}

/**
* Add apples
*
* @param Comakai\MyBundle\Entity\Apple $apples
*/
public function addApple(\Comakai\MyBundle\Entity\Apple $apples) {
$this->apples[] = $apples;
}

/**
* Get apples
*
* @return Doctrine\Common\Collections\Collection
*/
public function getApples() {
return $this->apples;
}


/**
* Add pigs
*
* @param Comakai\MyBundle\Entity\Pig $pigs
*/
public function addPig(\Comakai\MyBundle\Entity\Pig $pigs) {
$this->pigs[] = $pigs;
}

/**
* Get pigs
*
* @return Doctrine\Common\Collections\Collection
*/
public function getPigs() {
return $this->pigs;
}
}

和这个听众:

<?php

namespace Comakai\MyBundle\Listener;

use Comakai\MyBundle\Util\SluggerParser
Doctrine\ORM\Event\OnFlushEventArgs,
Comakai\MyBundle\Entity\Stuff,
Comakai\MyBundle\Entity\Apple,
Comakai\MyBundle\Entity\Pig;

class Listener {

/**
* @param \Doctrine\ORM\Event\OnFlushEventArgs $ea
*/
public function onFlush(OnFlushEventArgs $ea) {

$em = $ea->getEntityManager();
$uow = $em->getUnitOfWork();

foreach ($uow->getScheduledEntityInsertions() AS $entity) {

$this->save($entity, $em, $uow);

}

foreach ($uow->getScheduledEntityUpdates() AS $entity) {

$this->save($entity, $em, $uow);

}
}

public function save($entity, $em, $uow) {

if ($entity instanceof Stuff) {

$pigRepository = $em->getRepository('Comakai\MyBundle\Entity\Pig');
$content = $entity->getContent();

preg_match_all('/@@ pig:(\d+) @@/i', $content, $matches);
$entity->getPigs()->clear();

foreach($matches[1] as $pigID) {

$pig = $pigRepository->find($pigID);

if(!empty($pig)) {

$entity->addPig($pig);

}

}

$entity->setContent($content);

$meta = $em->getClassMetadata(get_class($entity));
$uow->recomputeSingleEntityChangeSet($meta, $entity);
$uow->computeChangeSet($meta, $entity);

}
}

}

如果 apple 的集合为空,它工作正常,但如果它有一些项目,我会收到重复错误。

如何告诉 UnitOfWork 我只想重新计算 pig 的集合?

更新

有一个新的 preFlush 事件 ( https://github.com/doctrine/doctrine2/pull/169 ),我认为这种事情可以在那里完成。该 PR 不在我正在使用的分支中,但让我们试试吧!

最佳答案

在监听器的 onFlush 事件期间更新实体时,您只需调用 computeChangeSet():

// make changes to entity
$entity->field = 'value';

// or assign an existing entity to an assocation
$entity->user = $myExistingUserEntity;
$entity->tags->add($myExistingTagEntity);

$meta = $em->getClassMetadata(get_class($entity));
$uow->computeChangeSet($meta, $entity);

如果您还要创建其他实体,则需要持久化它们并首先计算它们的更改!

$myNewUserEntity = new Entity\User;
$myNewTagEntity = new Entity\Tag;

$entity->user = $myNewUserEntity;
// make sure you call add() on the owning side for *ToMany associations
$entity->tags->add($myNewTagEntity);

$em->persist($myNewUserEntity);
$em->persist($myNewTagEntity);

$metaUser = $em->getClassMetadata(get_class($myNewUserEntity));
$uow->computeChangeSet($metaUser, $myNewUserEntity);

$metaTag = $em->getClassMetadata(get_class($myNewTagEntity));
$uow->computeChangeSet($metaTag, $myNewTagEntity);

$meta = $em->getClassMetadata(get_class($entity));
$uow->computeChangeSet($meta, $entity);

关于php - 如何在 onFlush 事件监听器中更新实体的 manyToMany 集合?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10866143/

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