更新postFlush / preFlush上的非规范化值?

时间:2013-11-17 03:30:56

标签: symfony doctrine-orm

我正在尝试找出更新数据库中的非规范化值的最佳过程。

以下是该方案:

Scenario: Update Activity Duration
    Given the following Task:
    | id | name   | duration
    | 1  | Task 1 | 0
    And the following Activity:
    | id | name       | startedAt        | endedAt | task |
    | 1  | Activity 1 | 2013-01-01 12:00 | null    | 1    |
    When I set "Activity 1" endedAt to "2013-01-01 13:00"
    And persist "Activity 1"
    Then "Activity 1" duration should be 3600
    And "Task 1" duration should be 3600

从数据结构中可以看出Task.duration是Activity.duration的非规范化和。

我正在努力的是何时更新Activity.duration和Task.duration。

可以在setEndedAt方法中计算Activity.duration。

Task.duration有点棘手。我想我需要在修改Activity时重新计算postFlush事件中的Task.duration。我假设它必须是postFlush因为我想在数据库中总结活动持续时间而不是获取所有Task.acitivities并在PHP中循环它们。

此外,我希望能够一次更新多个活动(想一想评论/编辑时间表)。在这种情况下,我认为我需要推迟刷新,因此工作单元包含所有修改过的活动。

文档实际上说:

  

在EntityManager #flush()结束时调用postFlush。无法在侦听器内安全地调用EntityManager#flush()。

可能会将这种方法统一起来。

建议的解决方案似乎有效吗?我无法看到这种方法可以在preFlush或onFlush中完成,因为持续时间尚未保存到DB。

Cheers Leevi

1 个答案:

答案 0 :(得分:0)

你可能会使用onFlushpreUpdate,但我觉得这种方法会不必要地将你的域对象与Doctrine结合起来。最好的解决方案是不要使用Doctrine的事件。

在更改startedAt的{​​{1}}或endedAt值之前,您可以从Activity中减去之前的持续时间,然后重新添加。

Task

当然,考虑到实际情况(没有开始时间,将活动从一个任务转移到另一个任务等),实际实施必须稍微复杂一些。)