我有很多很多这样的协会
Entity Car
{
/**
* @var \Doctrine\Common\Collections\Collection
*
* @ORM\ManyToMany(targetEntity="User", inversedBy="cars", fetch="EXTRA_LAZY")
* @ORM\JoinTable(
* name="cars_users",
* joinColumns={
* @ORM\JoinColumn(name="car_id", referencedColumnName="id")
* },
* inverseJoinColumns={
* @ORM\JoinColumn(name="user_id", referencedColumnName="id")
* }
* )
*/
protected $users;
/**
* @param $user
*/
public function removeUser(User $user)
{
if (!$this->users->contains($user)) {
return;
}
$this->users->removeElement($user);
$user->removeCar($this);
return $this;
}
}
Entity User
{
/**
* @var \Doctrine\Common\Collections\Collection
*
* @ORM\ManyToMany(targetEntity="Car", mappedBy="users")
*/
protected $cars;
}
在我的控制器里我有
$carA = getRandomCar();
$userB = getAUserThatBelongToCarA();
//remove association between Car A and User B
$carA->removesUser($userB);
doctrineUpdateCar($carA);
我有一个Doctrine Listener CarListener
我试图找出是否已在该听众中删除了User
并告知该User
是哪个。
我尝试preUpdate
postUpdate
postFlush
但无法找到在$userB
CarListener
对象的方法
答案 0 :(得分:9)
我建议您使用onflush事件让侦听器/订阅者监听,因为它是在计算更改后调度的,但是在执行对数据库的任何操作之前。这使得它非常理想,因为您可以访问即将进行的所有更改,但实际上还没有将它们写入数据库(因此您可以选择中止)。
侦听器/订阅者传递一个OnFlushEventArgs
对象,您可以从该对象访问UnitOfWork。工作单元有5种方法来收集即将进行的更改:
getScheduledEntityInsertions()
getScheduledEntityUpdates()
getScheduledEntityDeletions()
getScheduledCollectionUpdates()
getScheduledCollectionDeletions()
您正在做的是从集合User
中删除Car::$users
并从集合Car
中删除User::cars
。
因此,实际上没有实体被删除,没有任何字段被更改。而不是你改变收藏。换句话说,它是你想看的getScheduledCollectionUpdates()
。
getScheduledCollectionUpdates()
返回的集合是PersistentCollection的一个实例,它使用这些方法告诉您发生了哪些变化:
getInsertDiff()
getDeleteDiff()
在您的情况下,您可以使用getDeleteDiff()
找出已从集合中删除的实体。
答案 1 :(得分:0)
您的preUpdate
侦听器将收到一个PreUpdateEventArgs
对象,您可以使用该对象获取有关使用hasChangedField()
等方法保留的更改的大量信息。更多信息:
http://doctrine-orm.readthedocs.org/projects/doctrine-orm/en/latest/reference/events.html#preupdate
答案 2 :(得分:0)
教义确实表现得很奇怪......在更复杂的环境中遇到同样的问题。所以我决定从你的例子中复制汽车和用户类。除了car实体中的removeUser函数之外,使用完全相同的实体。认为这会短得多:
class Car
{
public function removeUser(User $user)
{
$this->users->removeElement($user);
}
}
在控制器中我得到了这个:
$em = $this->getDoctrine()->getManager();
$cars = $this->getDoctrine()->getRepository('AppBundle:Car');
$users = $this->getDoctrine()->getRepository('AppBundle:User');
$car = $cars->findOneById(2);
$removeUser = $users->findOneById(3);
$car->removeUser($removeUser);
// $em->flush();
ID#3的用户总是从汽车#2中移除。无论car_user表中的条目是否存在,都会执行DELETE语句。
如果我在EntityManager
($ em)上的flush方法中发表评论,则会调用onFlush
事件。 UnitOfWork对象上的函数getScheduledEntityInsertions()
,getScheduledEntityUpdates()
,getScheduledEntityDeletions()
,getScheduledCollectionDeletions()
和getScheduledCollectionUpdates()
只返回空数组......
我认为最简单的方法是通知自己这些变化。找到一种简单的方法来手动跟踪注释。以下是链接: