Rajout de doctrine/orm
[zf2.biz/galerie.git] / vendor / doctrine / orm / UPGRADE.md
1 # Upgrade to 2.3
2
3 ## EntityGenerator add*() method generation
4
5 When generating an add*() method for a collection the EntityGenerator will now not
6 use the Type-Hint to get the singular for the collection name, but use the field-name
7 and strip a trailing "s" character if there is one.
8
9 ## Merge copies non persisted properties too
10
11 When merging an entity in UoW not only mapped properties are copied, but also others.
12
13 ## Query, QueryBuilder and NativeQuery parameters *BC break*
14
15 From now on, parameters in queries is an ArrayCollection instead of a simple array.
16 This affects heavily the usage of setParameters(), because it will not append anymore
17 parameters to query, but will actually override the already defined ones.
18 Whenever you are retrieving a parameter (ie. $query->getParameter(1)), you will
19 receive an instance of Query\Parameter, which contains the methods "getName",
20 "getValue" and "getType". Parameters are also only converted to when necessary, and
21 not when they are set.
22
23 Also, related functions were affected:
24
25 * execute($parameters, $hydrationMode) the argument $parameters can be either an key=>value array or an ArrayCollection instance
26 * iterate($parameters, $hydrationMode) the argument $parameters can be either an key=>value array or an ArrayCollection instance
27 * setParameters($parameters) the argument $parameters can be either an key=>value array or an ArrayCollection instance
28 * getParameters() now returns ArrayCollection instead of array
29 * getParameter($key) now returns Parameter instance instead of parameter value
30
31 ## Query TreeWalker method renamed
32
33 Internal changes were made to DQL and SQL generation. If you have implemented your own TreeWalker,
34 you probably need to update it. The method walkJoinVariableDeclaration is now named walkJoin.
35
36 ## Metadata Drivers
37
38 Metadata drivers have been rewritten to reuse code from Doctrine\Common. Anyone who is using the
39 `Doctrine\ORM\Mapping\Driver\Driver` interface should instead refer to
40 `Doctrine\Common\Persistence\Mapping\Driver\MappingDriver`. Same applies to
41 `Doctrine\ORM\Mapping\Driver\AbstractFileDriver`: you should now refer to
42 `Doctrine\Common\Persistence\Mapping\Driver\FileDriver`.
43
44 Also, following mapping drivers have been deprecated, please use their replacements in Doctrine\Common as listed:
45
46  *  `Doctrine\ORM\Mapping\Driver\DriverChain`       => `Doctrine\Common\Persistence\Mapping\Driver\MappingDriverChain`
47  *  `Doctrine\ORM\Mapping\Driver\PHPDriver`         => `Doctrine\Common\Persistence\Mapping\Driver\PHPDriver`
48  *  `Doctrine\ORM\Mapping\Driver\StaticPHPDriver`   => `Doctrine\Common\Persistence\Mapping\Driver\StaticPHPDriver`
49
50 # Upgrade to 2.2
51
52 ## ResultCache implementation rewritten
53
54 The result cache is completely rewritten and now works on the database result level, not inside the ORM AbstractQuery
55 anymore. This means that for result cached queries the hydration will now always be performed again, regardless of
56 the hydration mode. Affected areas are:
57
58 1. Fixes the problem that entities coming from the result cache were not registered in the UnitOfWork
59    leading to problems during EntityManager#flush. Calls to EntityManager#merge are not necessary anymore.
60 2. Affects the array hydrator which now includes the overhead of hydration compared to caching the final result.
61
62 The API is backwards compatible however most of the getter methods on the `AbstractQuery` object are now
63 deprecated in favor of calling AbstractQuery#getQueryCacheProfile(). This method returns a `Doctrine\DBAL\Cache\QueryCacheProfile`
64 instance with access to result cache driver, lifetime and cache key.
65
66
67 ## EntityManager#getPartialReference() creates read-only entity
68
69 Entities returned from EntityManager#getPartialReference() are now marked as read-only if they
70 haven't been in the identity map before. This means objects of this kind never lead to changes
71 in the UnitOfWork.
72
73
74 ## Fields omitted in a partial DQL query or a native query are never updated
75
76 Fields of an entity that are not returned from a partial DQL Query or native SQL query
77 will never be updated through an UPDATE statement.
78
79
80 ## Removed support for onUpdate in @JoinColumn
81
82 The onUpdate foreign key handling makes absolutely no sense in an ORM. Additionally Oracle doesn't even support it. Support for it is removed.
83
84
85 ## Changes in Annotation Handling
86
87 There have been some changes to the annotation handling in Common 2.2 again, that affect how people with old configurations
88 from 2.0 have to configure the annotation driver if they don't use `Configuration::newDefaultAnnotationDriver()`:
89
90     // Register the ORM Annotations in the AnnotationRegistry
91     AnnotationRegistry::registerFile('path/to/Doctrine/ORM/Mapping/Driver/DoctrineAnnotations.php');
92
93     $reader = new \Doctrine\Common\Annotations\SimpleAnnotationReader();
94     $reader->addNamespace('Doctrine\ORM\Mapping');
95     $reader = new \Doctrine\Common\Annotations\CachedReader($reader, new ArrayCache());
96
97     $driver = new AnnotationDriver($reader, (array)$paths);
98
99     $config->setMetadataDriverImpl($driver);
100
101
102 ## Scalar mappings can now be ommitted from DQL result
103
104 You are now allowed to mark scalar SELECT expressions as HIDDEN an they are not hydrated anymore.
105 Example:
106
107 SELECT u, SUM(a.id) AS HIDDEN numArticles FROM User u LEFT JOIN u.Articles a ORDER BY numArticles DESC HAVING numArticles > 10
108
109 Your result will be a collection of Users, and not an array with key 0 as User object instance and "numArticles" as the number of articles per user
110
111
112 ## Map entities as scalars in DQL result
113
114 When hydrating to array or even a mixed result in object hydrator, previously you had the 0 index holding you entity instance.
115 You are now allowed to alias this, providing more flexibility for you code.
116 Example:
117
118 SELECT u AS user FROM User u
119
120 Will now return a collection of arrays with index "user" pointing to the User object instance.
121
122
123 ## Performance optimizations
124
125 Thousands of lines were completely reviewed and optimized for best performance.
126 Removed redundancy and improved code readability made now internal Doctrine code easier to understand.
127 Also, Doctrine 2.2 now is around 10-15% faster than 2.1.
128
129 ## EntityManager#find(null)
130
131 Previously EntityManager#find(null) returned null. It now throws an exception.
132
133 # Upgrade to 2.1
134
135 ## Interface for EntityRepository
136
137 The EntityRepository now has an interface Doctrine\Common\Persistence\ObjectRepository. This means that your classes that override EntityRepository and extend find(), findOneBy() or findBy() must be adjusted to follow this interface.
138
139 ## AnnotationReader changes
140
141 The annotation reader was heavily refactored between 2.0 and 2.1-RC1. In theory the operation of the new reader should be backwards compatible, but it has to be setup differently to work that way:
142
143     // new call to the AnnotationRegistry
144     \Doctrine\Common\Annotations\AnnotationRegistry::registerFile('/doctrine-src/lib/Doctrine/ORM/Mapping/Driver/DoctrineAnnotations.php');
145
146     $reader = new \Doctrine\Common\Annotations\AnnotationReader();
147     $reader->setDefaultAnnotationNamespace('Doctrine\ORM\Mapping\\');
148     // new code necessary starting here
149     $reader->setIgnoreNotImportedAnnotations(true);
150     $reader->setEnableParsePhpImports(false);
151     $reader = new \Doctrine\Common\Annotations\CachedReader(
152         new \Doctrine\Common\Annotations\IndexedReader($reader), new ArrayCache()
153     );
154
155 This is already done inside the ``$config->newDefaultAnnotationDriver``, so everything should automatically work if you are using this method. You can verify if everything still works by executing a console command such as schema-validate that loads all metadata into memory.
156
157 # Update from 2.0-BETA3 to 2.0-BETA4
158
159 ## XML Driver <change-tracking-policy /> element demoted to attribute
160
161 We changed how the XML Driver allows to define the change-tracking-policy. The working case is now:
162
163     <entity change-tracking-policy="DEFERRED_IMPLICT" />
164
165 # Update from 2.0-BETA2 to 2.0-BETA3
166
167 ## Serialization of Uninitialized Proxies
168
169 As of Beta3 you can now serialize uninitialized proxies, an exception will only be thrown when
170 trying to access methods on the unserialized proxy as long as it has not been re-attached to the
171 EntityManager using `EntityManager#merge()`. See this example:
172
173     $proxy = $em->getReference('User', 1);
174
175     $serializedProxy = serialize($proxy);
176     $detachedProxy = unserialized($serializedProxy);
177
178     echo $em->contains($detachedProxy); // FALSE
179
180     try {
181         $detachedProxy->getId(); // uninitialized detached proxy
182     } catch(Exception $e) {
183
184     }
185     $attachedProxy = $em->merge($detachedProxy);
186     echo $attackedProxy->getId(); // works!
187
188 ## Changed SQL implementation of Postgres and Oracle DateTime types
189
190 The DBAL Type "datetime" included the Timezone Offset in both Postgres and Oracle. As of this version they are now
191 generated without Timezone (TIMESTAMP WITHOUT TIME ZONE instead of TIMESTAMP WITH TIME ZONE).
192 See [this comment to Ticket DBAL-22](http://www.doctrine-project.org/jira/browse/DBAL-22?focusedCommentId=13396&page=com.atlassian.jira.plugin.system.issuetabpanels%3Acomment-tabpanel#action_13396)
193 for more details as well as migration issues for PostgreSQL and Oracle.
194
195 Both Postgres and Oracle will throw Exceptions during hydration of Objects with "DateTime" fields unless migration steps are taken!
196
197 ## Removed multi-dot/deep-path expressions in DQL
198
199 The support for implicit joins in DQL through the multi-dot/Deep Path Expressions
200 was dropped. For example:
201
202     SELECT u FROM User u WHERE u.group.name = ?1
203
204 See the "u.group.id" here is using multi dots (deep expression) to walk
205 through the graph of objects and properties. Internally the DQL parser
206 would rewrite these queries to:
207
208     SELECT u FROM User u JOIN u.group g WHERE g.name = ?1
209
210 This explicit notation will be the only supported notation as of now. The internal
211 handling of multi-dots in the DQL Parser was very complex, error prone in edge cases
212 and required special treatment for several features we added. Additionally
213 it had edge cases that could not be solved without making the DQL Parser
214 even much more complex. For this reason we will drop the support for the
215 deep path expressions to increase maintainability and overall performance
216 of the DQL parsing process. This will benefit any DQL query being parsed,
217 even those not using deep path expressions.
218
219 Note that the generated SQL of both notations is exactly the same! You
220 don't loose anything through this.
221
222 ## Default Allocation Size for Sequences
223
224 The default allocation size for sequences has been changed from 10 to 1. This step was made
225 to not cause confusion with users and also because it is partly some kind of premature optimization.
226
227 # Update from 2.0-BETA1 to 2.0-BETA2
228
229 There are no backwards incompatible changes in this release.
230
231 # Upgrade from 2.0-ALPHA4 to 2.0-BETA1
232
233 ## EntityRepository deprecates access to protected variables
234
235 Instead of accessing protected variables for the EntityManager in
236 a custom EntityRepository it is now required to use the getter methods
237 for all the three instance variables:
238
239 * `$this->_em` now accessible through `$this->getEntityManager()`
240 * `$this->_class` now accessible through `$this->getClassMetadata()`
241 * `$this->_entityName` now accessible through `$this->getEntityName()`
242
243 Important: For Beta 2 the protected visibility of these three properties will be
244 changed to private!
245
246 ## Console migrated to Symfony Console
247
248 The Doctrine CLI has been replaced by Symfony Console Configuration
249
250 Instead of having to specify:
251
252     [php]
253     $cliConfig = new CliConfiguration();
254     $cliConfig->setAttribute('em', $entityManager);
255
256 You now have to configure the script like:
257
258     [php]
259     $helperSet = new \Symfony\Components\Console\Helper\HelperSet(array(
260         'db' => new \Doctrine\DBAL\Tools\Console\Helper\ConnectionHelper($em->getConnection()),
261         'em' => new \Doctrine\ORM\Tools\Console\Helper\EntityManagerHelper($em)
262     ));
263
264 ## Console: No need for Mapping Paths anymore
265
266 In previous versions you had to specify the --from and --from-path options
267 to show where your mapping paths are from the console. However this information
268 is already known from the Mapping Driver configuration, so the requirement
269 for this options were dropped.
270
271 Instead for each console command all the entities are loaded and to
272 restrict the operation to one or more sub-groups you can use the --filter flag.
273
274 ## AnnotationDriver is not a default mapping driver anymore
275
276 In conjunction with the recent changes to Console we realized that the
277 annotations driver being a default metadata driver lead to lots of glue
278 code in the console components to detect where entities lie and how to load
279 them for batch updates like SchemaTool and other commands. However the
280 annotations driver being a default driver does not really help that much
281 anyways.
282
283 Therefore we decided to break backwards compability in this issue and drop
284 the support for Annotations as Default Driver and require our users to
285 specify the driver explicitly (which allows us to ask for the path to all
286 entities).
287
288 If you are using the annotations metadata driver as default driver, you
289 have to add the following lines to your bootstrap code:
290
291     $driverImpl = $config->newDefaultAnnotationDriver(array(__DIR__."/Entities"));
292     $config->setMetadataDriverImpl($driverImpl);
293
294 You have to specify the path to your entities as either string of a single
295 path or array of multiple paths
296 to your entities. This information will be used by all console commands to
297 access all entities.
298
299 Xml and Yaml Drivers work as before!
300
301
302 ## New inversedBy attribute
303
304 It is now *mandatory* that the owning side of a bidirectional association specifies the
305 'inversedBy' attribute that points to the name of the field on the inverse side that completes
306 the association. Example:
307
308     [php]
309     // BEFORE (ALPHA4 AND EARLIER)
310     class User
311     {
312         //...
313         /** @OneToOne(targetEntity="Address", mappedBy="user") */
314         private $address;
315         //...
316     }
317     class Address
318     {
319         //...
320         /** @OneToOne(targetEntity="User") */
321         private $user;
322         //...
323     }
324
325     // SINCE BETA1
326     // User class DOES NOT CHANGE
327     class Address
328     {
329         //...
330         /** @OneToOne(targetEntity="User", inversedBy="address") */
331         private $user;
332         //...
333     }
334
335 Thus, the inversedBy attribute is the counterpart to the mappedBy attribute. This change
336 was necessary to enable some simplifications and further performance improvements. We
337 apologize for the inconvenience.
338
339 ## Default Property for Field Mappings
340
341 The "default" option for database column defaults has been removed. If desired, database column defaults can
342 be implemented by using the columnDefinition attribute of the @Column annotation (or the approriate XML and YAML equivalents).
343 Prefer PHP default values, if possible.
344
345 ## Selecting Partial Objects
346
347 Querying for partial objects now has a new syntax. The old syntax to query for partial objects
348 now has a different meaning. This is best illustrated by an example. If you previously
349 had a DQL query like this:
350
351     [sql]
352     SELECT u.id, u.name FROM User u
353
354 Since BETA1, simple state field path expressions in the select clause are used to select
355 object fields as plain scalar values (something that was not possible before).
356 To achieve the same result as previously (that is, a partial object with only id and name populated)
357 you need to use the following, explicit syntax:
358
359     [sql]
360     SELECT PARTIAL u.{id,name} FROM User u
361
362 ## XML Mapping Driver
363
364 The 'inheritance-type' attribute changed to take last bit of ClassMetadata constant names, i.e.
365 NONE, SINGLE_TABLE, INHERITANCE_TYPE_JOINED
366
367 ## YAML Mapping Driver
368
369 The way to specify lifecycle callbacks in YAML Mapping driver was changed to allow for multiple callbacks
370 per event. The Old syntax ways:
371
372     [yaml]
373     lifecycleCallbacks:
374       doStuffOnPrePersist: prePersist
375       doStuffOnPostPersist: postPersist
376
377 The new syntax is:
378
379     [yaml]
380     lifecycleCallbacks:
381       prePersist: [ doStuffOnPrePersist, doOtherStuffOnPrePersistToo ]
382       postPersist: [ doStuffOnPostPersist ]
383
384 ## PreUpdate Event Listeners
385
386 Event Listeners listening to the 'preUpdate' event can only affect the primitive values of entity changesets
387 by using the API on the `PreUpdateEventArgs` instance passed to the preUpdate listener method. Any changes
388 to the state of the entitys properties won't affect the database UPDATE statement anymore. This gives drastic
389 performance benefits for the preUpdate event.
390
391 ## Collection API
392
393 The Collection interface in the Common package has been updated with some missing methods
394 that were present only on the default implementation, ArrayCollection. Custom collection
395 implementations need to be updated to adhere to the updated interface.
396
397 # Upgrade from 2.0-ALPHA3 to 2.0-ALPHA4
398
399 ## CLI Controller changes
400
401 CLI main object changed its name and namespace. Renamed from Doctrine\ORM\Tools\Cli to Doctrine\Common\Cli\CliController.
402 Doctrine\Common\Cli\CliController now only deals with namespaces. Ready to go, Core, Dbal and Orm are available and you can subscribe new tasks by retrieving the namespace and including new task. Example:
403
404     [php]
405     $cli->getNamespace('Core')->addTask('my-example', '\MyProject\Tools\Cli\Tasks\MyExampleTask');
406
407
408 ## CLI Tasks documentation
409
410 Tasks have implemented a new way to build documentation. Although it is still possible to define the help manually by extending the basicHelp and extendedHelp, they are now optional.
411 With new required method AbstractTask::buildDocumentation, its implementation defines the TaskDocumentation instance (accessible through AbstractTask::getDocumentation()), basicHelp and extendedHelp are now not necessary to be implemented.
412
413 ## Changes in Method Signatures
414
415     * A bunch of Methods on both Doctrine\DBAL\Platforms\AbstractPlatform and Doctrine\DBAL\Schema\AbstractSchemaManager
416       have changed quite significantly by adopting the new Schema instance objects.
417
418 ## Renamed Methods
419
420     * Doctrine\ORM\AbstractQuery::setExpireResultCache() -> expireResultCache()
421     * Doctrine\ORM\Query::setExpireQueryCache() -> expireQueryCache()
422
423 ## SchemaTool Changes
424
425     * "doctrine schema-tool --drop" now always drops the complete database instead of
426     only those tables defined by the current database model. The previous method had
427     problems when foreign keys of orphaned tables pointed to tables that were schedulded
428     for deletion.
429     * Use "doctrine schema-tool --update" to get a save incremental update for your
430     database schema without deleting any unused tables, sequences or foreign keys.
431     * Use "doctrine schema-tool --complete-update" to do a full incremental update of
432     your schema.
433 # Upgrade from 2.0-ALPHA2 to 2.0-ALPHA3
434
435 This section details the changes made to Doctrine 2.0-ALPHA3 to make it easier for you
436 to upgrade your projects to use this version.
437
438 ## CLI Changes
439
440 The $args variable used in the cli-config.php for configuring the Doctrine CLI has been renamed to $globalArguments.
441
442 ## Proxy class changes
443
444 You are now required to make supply some minimalist configuration with regards to proxy objects. That involves 2 new configuration options. First, the directory where generated proxy classes should be placed needs to be specified. Secondly, you need to configure the namespace used for proxy classes. The following snippet shows an example:
445
446     [php]
447     // step 1: configure directory for proxy classes
448     // $config instanceof Doctrine\ORM\Configuration
449     $config->setProxyDir('/path/to/myproject/lib/MyProject/Generated/Proxies');
450     $config->setProxyNamespace('MyProject\Generated\Proxies');
451
452 Note that proxy classes behave exactly like any other classes when it comes to class loading. Therefore you need to make sure the proxy classes can be loaded by some class loader. If you place the generated proxy classes in a namespace and directory under your projects class files, like in the example above, it would be sufficient to register the MyProject namespace on a class loader. Since the proxy classes are contained in that namespace and adhere to the standards for class loading, no additional work is required.
453 Generating the proxy classes into a namespace within your class library is the recommended setup.
454
455 Entities with initialized proxy objects can now be serialized and unserialized properly from within the same application.
456
457 For more details refer to the Configuration section of the manual.
458
459 ## Removed allowPartialObjects configuration option
460
461 The allowPartialObjects configuration option together with the `Configuration#getAllowPartialObjects` and `Configuration#setAllowPartialObjects` methods have been removed.
462 The new behavior is as if the option were set to FALSE all the time, basically disallowing partial objects globally. However, you can still use the `Query::HINT_FORCE_PARTIAL_LOAD` query hint to force a query to return partial objects for optimization purposes.
463
464 ## Renamed Methods
465
466 * Doctrine\ORM\Configuration#getCacheDir() to getProxyDir()
467 * Doctrine\ORM\Configuration#setCacheDir($dir) to setProxyDir($dir)