如何通过注释禁用Doctrine persist cascade?

时间:2016-05-05 16:45:02

标签: symfony doctrine-orm doctrine

考虑以下两个类:

/**
 * @ORM\Table(name="notifications")
 */
class Notification {

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

    /**
     * @ORM\ManyToOne(targetEntity="Task")
     * @ORM\JoinColumn(name="task_id", referencedColumnName="id", onDelete="CASCADE")
     */
    private $task;

}


/**
 * @ORM\Table(name="tasks")
 */
class Task {

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

    /**
     * @var integer
     *
     * @ORM\Column(name="status", type="smallint")
     */
    private $status;

}

在我的控制器中我有

$task = $em->getRepository("AppBundle:Task")->find(1);
$task->setStatus(1);

$notification = new Notification();
$notification->setTask($task);

$em->persist($notification);
$em->flush();

我的问题是,当我坚持task时,如何避免持久$notification?使用上面的代码,它还会将task状态更改为1.

我知道我可以做类似下面的事情,但我想知道是否可以用注释做到这一点?

$em->flush($notification);

为什么Doctrine坚持ManyToOne的另一面?

1 个答案:

答案 0 :(得分:3)

持续级联与此无关。例如,这仍将更新任务:

$task = $em->getRepository("AppBundle:Task")->find(1);
$task->setStatus(1);
$em->flush();

一个常见的误解是持久化实体意味着它被某种方式标记为准备更新,但事实并非如此。

Persisting an entity表示实体现在由实体经理管理。

任何托管实体的更改都将在flush上提交,如果实体已经被管理,则persist不会更改。

对于您的任务对象,您已经使用实体管理器获取了它,因此它被视为托管,并且您对其进行的任何更新都将在flush上提交,无论您是否对其进行持久调用。

总之,如果您不希望通过全局刷新更新托管实体,或者仅对您特意要保存到数据库的实体进行调用 - >刷新,则不要更新托管实体。

更多信息:

https://www.doctrine-project.org/projects/doctrine-orm/en/2.6/reference/working-with-objects.html#synchronization-with-the-database