Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Newer
Older
100644 152 lines (122 sloc) 5.246 kB
1bfeaf3 @beberlei Initial conversion from Markdown to ReST - Finalized Cookbook
beberlei authored
1 Change Tracking Policies
a5a0dfa @beberlei Converted ORM Docs into ReST
beberlei authored
2 ========================
1bfeaf3 @beberlei Initial conversion from Markdown to ReST - Finalized Cookbook
beberlei authored
3
4 Change tracking is the process of determining what has changed in
5 managed entities since the last time they were synchronized with
6 the database.
7
8 Doctrine provides 3 different change tracking policies, each having
9 its particular advantages and disadvantages. The change tracking
10 policy can be defined on a per-class basis (or more precisely,
11 per-hierarchy).
12
13 Deferred Implicit
14 ~~~~~~~~~~~~~~~~~
15
16 The deferred implicit policy is the default change tracking policy
17 and the most convenient one. With this policy, Doctrine detects the
18 changes by a property-by-property comparison at commit time and
19 also detects changes to entities or new entities that are
20 referenced by other managed entities ("persistence by
21 reachability"). Although the most convenient policy, it can have
22 negative effects on performance if you are dealing with large units
23 of work (see "Understanding the Unit of Work"). Since Doctrine
24 can't know what has changed, it needs to check all managed entities
25 for changes every time you invoke EntityManager#flush(), making
26 this operation rather costly.
27
28 Deferred Explicit
29 ~~~~~~~~~~~~~~~~~
30
31 The deferred explicit policy is similar to the deferred implicit
32 policy in that it detects changes through a property-by-property
22ab3d1 @beberlei Fixed several issues and merged pull requests into docs.
beberlei authored
33 comparison at commit time. The difference is that Doctrine 2 only
34 considers entities that have been explicitly marked for change detection
1bfeaf3 @beberlei Initial conversion from Markdown to ReST - Finalized Cookbook
beberlei authored
35 through a call to EntityManager#persist(entity) or through a save
36 cascade. All other entities are skipped. This policy therefore
37 gives improved performance for larger units of work while
38 sacrificing the behavior of "automatic dirty checking".
39
40 Therefore, flush() operations are potentially cheaper with this
41 policy. The negative aspect this has is that if you have a rather
42 large application and you pass your objects through several layers
43 for processing purposes and business tasks you may need to track
44 yourself which entities have changed on the way so you can pass
45 them to EntityManager#persist().
46
47 This policy can be configured as follows:
48
4698346 @beberlei Finialized ReST doc changes, merged changes from latest Markdown docs.
beberlei authored
49 .. code-block:: php
1bfeaf3 @beberlei Initial conversion from Markdown to ReST - Finalized Cookbook
beberlei authored
50
51 <?php
52 /**
53 * @Entity
54 * @ChangeTrackingPolicy("DEFERRED_EXPLICIT")
55 */
56 class User
57 {
58 // ...
59 }
60
61 Notify
62 ~~~~~~
63
64 This policy is based on the assumption that the entities notify
65 interested listeners of changes to their properties. For that
66 purpose, a class that wants to use this policy needs to implement
67 the ``NotifyPropertyChanged`` interface from the Doctrine
68 namespace. As a guideline, such an implementation can look as
69 follows:
70
4698346 @beberlei Finialized ReST doc changes, merged changes from latest Markdown docs.
beberlei authored
71 .. code-block:: php
1bfeaf3 @beberlei Initial conversion from Markdown to ReST - Finalized Cookbook
beberlei authored
72
73 <?php
74 use Doctrine\Common\NotifyPropertyChanged,
75 Doctrine\Common\PropertyChangedListener;
76
77 /**
78 * @Entity
79 * @ChangeTrackingPolicy("NOTIFY")
80 */
81 class MyEntity implements NotifyPropertyChanged
82 {
83 // ...
84
85 private $_listeners = array();
86
87 public function addPropertyChangedListener(PropertyChangedListener $listener)
88 {
89 $this->_listeners[] = $listener;
90 }
91 }
92
93 Then, in each property setter of this class or derived classes, you
94 need to notify all the ``PropertyChangedListener`` instances. As an
95 example we add a convenience method on ``MyEntity`` that shows this
96 behaviour:
97
4698346 @beberlei Finialized ReST doc changes, merged changes from latest Markdown docs.
beberlei authored
98 .. code-block:: php
1bfeaf3 @beberlei Initial conversion from Markdown to ReST - Finalized Cookbook
beberlei authored
99
100 <?php
101 // ...
102
103 class MyEntity implements NotifyPropertyChanged
104 {
105 // ...
106
107 protected function _onPropertyChanged($propName, $oldValue, $newValue)
108 {
109 if ($this->_listeners) {
110 foreach ($this->_listeners as $listener) {
111 $listener->propertyChanged($this, $propName, $oldValue, $newValue);
112 }
113 }
114 }
115
116 public function setData($data)
117 {
118 if ($data != $this->data) {
119 $this->_onPropertyChanged('data', $this->data, $data);
120 $this->data = $data;
121 }
122 }
123 }
124
125 You have to invoke ``_onPropertyChanged`` inside every method that
126 changes the persistent state of ``MyEntity``.
127
128 The check whether the new value is different from the old one is
129 not mandatory but recommended. That way you also have full control
130 over when you consider a property changed.
131
132 The negative point of this policy is obvious: You need implement an
133 interface and write some plumbing code. But also note that we tried
134 hard to keep this notification functionality abstract. Strictly
135 speaking, it has nothing to do with the persistence layer and the
136 Doctrine ORM or DBAL. You may find that property notification
137 events come in handy in many other scenarios as well. As mentioned
138 earlier, the ``Doctrine\Common`` namespace is not that evil and
139 consists solely of very small classes and interfaces that have
140 almost no external dependencies (none to the DBAL and none to the
141 ORM) and that you can easily take with you should you want to swap
142 out the persistence layer. This change tracking policy does not
143 introduce a dependency on the Doctrine DBAL/ORM or the persistence
144 layer.
145
146 The positive point and main advantage of this policy is its
147 effectiveness. It has the best performance characteristics of the 3
148 policies with larger units of work and a flush() operation is very
149 cheap when nothing has changed.
150
151
Something went wrong with that request. Please try again.