1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
2191
2192
2193
2194
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208
2209
2210
2211
2212
2213
2214
2215
2216
2217
2218
2219
2220
2221
2222
2223
2224
2225
2226
2227
2228
2229
2230
2231
2232
2233
2234
2235
2236
2237
2238
2239
2240
2241
2242
2243
2244
2245
2246
2247
2248
2249
2250
2251
2252
2253
2254
2255
2256
2257
2258
2259
2260
2261
2262
2263
2264
2265
2266
2267
2268
2269
2270
2271
2272
2273
2274
2275
2276
2277
2278
2279
2280
2281
2282
2283
2284
2285
2286
2287
2288
2289
2290
2291
2292
2293
2294
2295
2296
2297
2298
2299
2300
2301
2302
2303
|
# Upgrade to 3.2
## Deprecate the `NotSupported` exception
The class `Doctrine\ORM\Exception\NotSupported` is deprecated without replacement.
## Deprecate remaining `Serializable` implementation
Relying on `SequenceGenerator` implementing the `Serializable` is deprecated
because that interface won't be implemented in ORM 4 anymore.
The following methods are deprecated:
* `SequenceGenerator::serialize()`
* `SequenceGenerator::unserialize()`
## `orm:schema-tool:update` option `--complete` is deprecated
That option behaves as a no-op, and is deprecated. It will be removed in 4.0.
## Deprecate properties `$indexes` and `$uniqueConstraints` of `Doctrine\ORM\Mapping\Table`
The properties `$indexes` and `$uniqueConstraints` have been deprecated since they had no effect at all.
The preferred way of defining indices and unique constraints is by
using the `\Doctrine\ORM\Mapping\UniqueConstraint` and `\Doctrine\ORM\Mapping\Index` attributes.
# Upgrade to 3.1
## Deprecate `Doctrine\ORM\Mapping\ReflectionEnumProperty`
This class is deprecated and will be removed in 4.0.
Instead, use `Doctrine\Persistence\Reflection\EnumReflectionProperty` from
`doctrine/persistence`.
## Deprecate passing null to `ClassMetadata::fullyQualifiedClassName()`
Passing `null` to `Doctrine\ORM\ClassMetadata::fullyQualifiedClassName()` is
deprecated and will no longer be possible in 4.0.
## Deprecate array access
Using array access on instances of the following classes is deprecated:
- `Doctrine\ORM\Mapping\DiscriminatorColumnMapping`
- `Doctrine\ORM\Mapping\EmbedClassMapping`
- `Doctrine\ORM\Mapping\FieldMapping`
- `Doctrine\ORM\Mapping\JoinColumnMapping`
- `Doctrine\ORM\Mapping\JoinTableMapping`
# Upgrade to 3.0
## BC BREAK: Calling `ClassMetadata::getAssociationMappedByTargetField()` with the owning side of an association now throws an exception
Previously, calling
`Doctrine\ORM\Mapping\ClassMetadata::getAssociationMappedByTargetField()` with
the owning side of an association returned `null`, which was undocumented, and
wrong according to the phpdoc of the parent method.
If you do not know whether you are on the owning or inverse side of an association,
you can use `Doctrine\ORM\Mapping\ClassMetadata::isAssociationInverseSide()`
to find out.
## BC BREAK: `Doctrine\ORM\Proxy\Autoloader` no longer extends `Doctrine\Common\Proxy\Autoloader`
Make sure to use the former when writing a type declaration or an `instanceof` check.
## Minor BC BREAK: Changed order of arguments passed to `OneToOne`, `ManyToOne` and `Index` mapping PHP attributes
To keep PHP mapping attributes consistent, order of arguments passed to above attributes has been changed
so `$targetEntity` is a first argument now. This change affects only non-named arguments usage.
## BC BREAK: AUTO keyword for identity generation defaults to IDENTITY for PostgreSQL when using `doctrine/dbal` 4
When using the `AUTO` strategy to let Doctrine determine the identity generation mechanism for
an entity, and when using `doctrine/dbal` 4, PostgreSQL now uses `IDENTITY`
instead of `SEQUENCE` or `SERIAL`.
* If you want to upgrade your existing tables to identity columns, you will need to follow [migration to identity columns on PostgreSQL](https://www.doctrine-project.org/projects/doctrine-dbal/en/4.0/how-to/postgresql-identity-migration.html)
* If you want to keep using SQL sequences, you need to configure the ORM this way:
```php
use Doctrine\DBAL\Platforms\PostgreSQLPlatform;
use Doctrine\ORM\Configuration;
use Doctrine\ORM\Mapping\ClassMetadata;
assert($configuration instanceof Configuration);
$configuration->setIdentityGenerationPreferences([
PostgreSQLPlatform::CLASS => ClassMetadata::GENERATOR_TYPE_SEQUENCE,
]);
```
## BC BREAK: Throw exceptions when using illegal attributes on Embeddable
There are only a few attributes allowed on an embeddable such as `#[Column]` or
`#[Embedded]`. Previously all others that target entity classes where ignored,
now they throw an exception.
## BC BREAK: Partial objects are removed
- The `PARTIAL` keyword in DQL no longer exists.
- `Doctrine\ORM\Query\AST\PartialObjectExpression`is removed.
- `Doctrine\ORM\Query\SqlWalker::HINT_PARTIAL` and
`Doctrine\ORM\Query::HINT_FORCE_PARTIAL_LOAD` are removed.
- `Doctrine\ORM\EntityManager*::getPartialReference()` is removed.
## BC BREAK: `Doctrine\ORM\Persister\Entity\EntityPersister::executeInserts()` return type changed to `void`
Implementors should adapt to the new signature, and should call
`UnitOfWork::assignPostInsertId()` for each entry in the previously returned
array.
## BC BREAK: `Doctrine\ORM\Proxy\ProxyFactory` no longer extends abstract factory from `doctrine/common`
It is no longer possible to call methods, constants or properties inherited
from that class on a `ProxyFactory` instance.
`Doctrine\ORM\Proxy\ProxyFactory::createProxyDefinition()` and
`Doctrine\ORM\Proxy\ProxyFactory::resetUninitializedProxy()` are removed as well.
## BC BREAK: lazy ghosts are enabled unconditionally
`Doctrine\ORM\Configuration::setLazyGhostObjectEnabled()` and
`Doctrine\ORM\Configuration::isLazyGhostObjectEnabled()` are now no-ops and
will be deprecated in 3.1.0
## BC BREAK: collisions in identity map are unconditionally rejected
`Doctrine\ORM\Configuration::setRejectIdCollisionInIdentityMap()` and
`Doctrine\ORM\Configuration::isRejectIdCollisionInIdentityMapEnabled()` are now
no-ops and will be deprecated in 3.1.0.
## BC BREAK: Lifecycle callback mapping on embedded classes is now explicitly forbidden
Lifecycle callback mapping on embedded classes produced no effect, and is now
explicitly forbidden to point out mistakes.
## BC BREAK: The `NOTIFY` change tracking policy is removed
You should use `DEFERRED_EXPLICIT` instead.
## BC BREAK: `Mapping\Driver\XmlDriver::__construct()` third argument is now enabled by default
The third argument to
`Doctrine\ORM\Mapping\Driver\XmlDriver::__construct()` was introduced to
let users opt-in to XML validation, that is now always enabled by default.
As a consequence, the same goes for
`Doctrine\ORM\Mapping\Driver\SimplifiedXmlDriver`, and for
`Doctrine\ORM\ORMSetup::createXMLMetadataConfiguration()`.
## BC BREAK: `Mapping\Driver\AttributeDriver::__construct()` second argument is now a no-op
The second argument to
`Doctrine\ORM\Mapping\Driver\AttributeDriver::__construct()` was introduced to
let users opt-in to a new behavior, that is now always enforced, regardless of
the value of that argument.
## BC BREAK: `Query::setDQL()` and `Query::setFirstResult()` no longer accept `null`
The `$dqlQuery` argument of `Doctrine\ORM\Query::setDQL()` must always be a
string.
The `$firstResult` argument of `Doctrine\ORM\Query::setFirstResult()` must
always be an integer.
## BC BREAK: `orm:schema-tool:update` option `--complete` is now a no-op
`orm:schema-tool:update` now behaves as if `--complete` was provided,
regardless of whether it is provided or not.
## BC BREAK: Removed `Doctrine\ORM\Proxy\Proxy` interface.
Use `Doctrine\Persistence\Proxy` instead to check whether proxies are initialized.
## BC BREAK: Overriding fields or associations declared in other than mapped superclasses
As stated in the documentation, fields and associations may only be overridden when being inherited
from mapped superclasses. Overriding them for parent entity classes now throws a `MappingException`.
## BC BREAK: Undeclared entity inheritance now throws a `MappingException`
As soon as an entity class inherits from another entity class, inheritance has to
be declared by adding the appropriate configuration for the root entity.
## Removed `getEntityManager()` in `Doctrine\ORM\Event\OnClearEventArgs` and `Doctrine\ORM\Event\*FlushEventArgs`
Use `getObjectManager()` instead.
## BC BREAK: Removed `Doctrine\ORM\Mapping\ClassMetadataInfo` class
Use `Doctrine\ORM\Mapping\ClassMetadata` instead.
## BC BREAK: Removed `Doctrine\ORM\Event\LifecycleEventArgs` class.
Use one of the dedicated event classes instead:
* `Doctrine\ORM\Event\PrePersistEventArgs`
* `Doctrine\ORM\Event\PreUpdateEventArgs`
* `Doctrine\ORM\Event\PreRemoveEventArgs`
* `Doctrine\ORM\Event\PostPersistEventArgs`
* `Doctrine\ORM\Event\PostUpdateEventArgs`
* `Doctrine\ORM\Event\PostRemoveEventArgs`
* `Doctrine\ORM\Event\PostLoadEventArgs`
## BC BREAK: Removed `AttributeDriver::$entityAnnotationClasses` and `AttributeDriver::getReader()`
* If you need to change the behavior of `AttributeDriver::isTransient()`,
override that method instead.
* The attribute reader is internal to the driver and should not be accessed from outside.
## BC BREAK: Removed `Doctrine\ORM\Query\AST\InExpression`
The AST parser will create a `InListExpression` or a `InSubselectExpression` when
encountering an `IN ()` DQL expression instead of a generic `InExpression`.
As a consequence, `SqlWalker::walkInExpression()` has been replaced by
`SqlWalker::walkInListExpression()` and `SqlWalker::walkInSubselectExpression()`.
## BC BREAK: Changed `EntityManagerInterface#refresh($entity)`, `EntityManagerDecorator#refresh($entity)` and `UnitOfWork#refresh($entity)` signatures
The new signatures of these methods add an optional `LockMode|int|null $lockMode`
param with default `null` value (no lock).
## BC Break: Removed AnnotationDriver
The annotation driver and anything related to annotation has been removed.
Please migrate to another mapping driver.
The `Doctrine\ORM\Mapping\Annotation` maker interface has been removed in favor of the new
`Doctrine\ORM\Mapping\MappingAttribute` interface.
## BC BREAK: Removed `EntityManager::create()`
The constructor of `EntityManager` is now public and must be used instead of the `create()` method.
However, the constructor expects a `Connection` while `create()` accepted an array with connection parameters.
You can pass that array to DBAL's `Doctrine\DBAL\DriverManager::getConnection()` method to bootstrap the
connection.
## BC BREAK: Removed `QueryBuilder` methods and constants.
The following `QueryBuilder` constants and methods have been removed:
1. `SELECT`,
2. `DELETE`,
3. `UPDATE`,
4. `STATE_DIRTY`,
5. `STATE_CLEAN`,
6. `getState()`,
7. `getType()`.
## BC BREAK: Omitting only the alias argument for `QueryBuilder::update` and `QueryBuilder::delete` is not supported anymore
When building an UPDATE or DELETE query and when passing a class/type to the function, the alias argument must not be omitted.
### Before
```php
$qb = $em->createQueryBuilder()
->delete('User u')
->where('u.id = :user_id')
->setParameter('user_id', 1);
```
### After
```php
$qb = $em->createQueryBuilder()
->delete('User', 'u')
->where('u.id = :user_id')
->setParameter('user_id', 1);
```
## BC BREAK: Split output walkers and tree walkers
`SqlWalker` and its child classes don't implement the `TreeWalker` interface
anymore.
The following methods have been removed from the `TreeWalker` interface and
from the `TreeWalkerAdapter` and `TreeWalkerChain` classes:
* `setQueryComponent()`
* `walkSelectClause()`
* `walkFromClause()`
* `walkFunction()`
* `walkOrderByClause()`
* `walkOrderByItem()`
* `walkHavingClause()`
* `walkJoin()`
* `walkSelectExpression()`
* `walkQuantifiedExpression()`
* `walkSubselect()`
* `walkSubselectFromClause()`
* `walkSimpleSelectClause()`
* `walkSimpleSelectExpression()`
* `walkAggregateExpression()`
* `walkGroupByClause()`
* `walkGroupByItem()`
* `walkDeleteClause()`
* `walkUpdateClause()`
* `walkUpdateItem()`
* `walkWhereClause()`
* `walkConditionalExpression()`
* `walkConditionalTerm()`
* `walkConditionalFactor()`
* `walkConditionalPrimary()`
* `walkExistsExpression()`
* `walkCollectionMemberExpression()`
* `walkEmptyCollectionComparisonExpression()`
* `walkNullComparisonExpression()`
* `walkInExpression()`
* `walkInstanceOfExpression()`
* `walkLiteral()`
* `walkBetweenExpression()`
* `walkLikeExpression()`
* `walkStateFieldPathExpression()`
* `walkComparisonExpression()`
* `walkInputParameter()`
* `walkArithmeticExpression()`
* `walkArithmeticTerm()`
* `walkStringPrimary()`
* `walkArithmeticFactor()`
* `walkSimpleArithmeticExpression()`
* `walkPathExpression()`
* `walkResultVariable()`
* `getExecutor()`
The following changes have been made to the abstract `TreeWalkerAdapter` class:
* The method `setQueryComponent()` is now protected.
* The method `_getQueryComponents()` has been removed in favor of
`getQueryComponents()`.
## BC BREAK: Removed identity columns emulation through sequences
If the platform you are using does not support identity columns, you should
switch to the `SEQUENCE` strategy.
## BC BREAK: Made setters parameters mandatory
The following methods require an argument when being called. Pass `null`
instead of omitting the argument.
* `Doctrine\ORM\Event\OnClassMetadataNotFoundEventArgs::setFoundMetadata()`
* `Doctrine\ORM\AbstractQuery::setHydrationCacheProfile()`
* `Doctrine\ORM\AbstractQuery::setResultCache()`
* `Doctrine\ORM\AbstractQuery::setResultCacheProfile()`
## BC BREAK: New argument to `NamingStrategy::joinColumnName()`
### Before
```php
<?php
class MyStrategy implements NamingStrategy
{
/**
* @param string $propertyName A property name.
*/
public function joinColumnName($propertyName): string
{
// …
}
}
```
### After
The `class-string` type for `$className` can be inherited from the signature of
the interface.
```php
<?php
class MyStrategy implements NamingStrategy
{
/**
* {@inheritdoc}
*/
public function joinColumnName(string $propertyName, string $className): string
{
// …
}
}
```
## BC BREAK: Remove `StaticPHPDriver` and `DriverChain`
Use `Doctrine\Persistence\Mapping\Driver\StaticPHPDriver` and
`Doctrine\Persistence\Mapping\Driver\MappingDriverChain` from
`doctrine/persistence` instead.
## BC BREAK: `UnderscoreNamingStrategy` is number aware only
The second argument to `UnderscoreNamingStrategy::__construct()` was dropped,
the strategy can no longer be unaware of numbers.
## BC BREAK: Remove `Doctrine\ORM\Tools\DisconnectedClassMetadataFactory`
No replacement is provided.
## BC BREAK: Remove support for `Type::canRequireSQLConversion()`
This feature was deprecated in DBAL 3.3.0 and will be removed in DBAL 4.0.
The value conversion methods are now called regardless of the type.
The `MappingException::sqlConversionNotAllowedForIdentifiers()` method has been removed
as no longer relevant.
## BC Break: Removed the `doctrine` binary.
The documentation explains how the console tools can be bootstrapped for
standalone usage:
https://www.doctrine-project.org/projects/doctrine-orm/en/stable/reference/tools.html
The method `ConsoleRunner::printCliConfigTemplate()` has been removed as well
because it was only useful in the context of the `doctrine` binary.
## BC Break: Removed `EntityManagerHelper` and related logic
All console commands require a `$entityManagerProvider` to be passed via the
constructor. Commands won't try to get the entity manager from a previously
registered `em` console helper.
The following classes have been removed:
* `Doctrine\ORM\Tools\Console\EntityManagerProvider\HelperSetManagerProvider`
* `Doctrine\ORM\Tools\Console\Helper\EntityManagerHelper`
The following breaking changes have been applied to `Doctrine\ORM\Tools\Console\ConsoleRunner`:
* The method `createHelperSet()` has been removed.
* The methods `run()` and `createApplication()` don't accept an instance of
`HelperSet` as first argument anymore.
* The method `addCommands()` requires an instance of `EntityManagerProvider`
as second argument now.
## BC Break: `Exception\ORMException` is no longer a class, but an interface
All methods in `Doctrine\ORM\ORMException` have been extracted to dedicated exceptions.
* `missingMappingDriverImpl()` => `Exception\MissingMappingDriverImplementation::create()`
* `unrecognizedField()` => `Persisters\Exception\UnrecognizedField::byName()`
* `unexpectedAssociationValue()` => `Exception\UnexpectedAssociationValue::create()`
* `invalidOrientation()` => `Persisters\Exception\InvalidOrientation::fromClassNameAndField()`
* `entityManagerClosed()` => `Exception\EntityManagerClosed::create()`
* `invalidHydrationMode()` => `Exception\InvalidHydrationMode::fromMode()`
* `mismatchedEventManager()` => `Exception\MismatchedEventManager::create()`
* `findByRequiresParameter()` => `Repository\Exception\InvalidMagicMethodCall::onMissingParameter()`
* `invalidMagicCall()` => `Repository\Exception\InvalidMagicMethodCall::becauseFieldNotFoundIn()`
* `invalidFindByInverseAssociation()` => `Repository\Exception\InvalidFindByCall::fromInverseSideUsage()`
* `invalidResultCacheDriver()` => `Cache\Exception\InvalidResultCacheDriver::create()`
* `notSupported()` => `Exception\NotSupported::create()`
* `queryCacheNotConfigured()` => `QueryCacheNotConfigured::create()`
* `metadataCacheNotConfigured()` => `Cache\Exception\MetadataCacheNotConfigured::create()`
* `queryCacheUsesNonPersistentCache()` => `Cache\Exception\QueryCacheUsesNonPersistentCache::fromDriver()`
* `metadataCacheUsesNonPersistentCache()` => `Cache\Exception\MetadataCacheUsesNonPersistentCache::fromDriver()`
* `proxyClassesAlwaysRegenerating()` => `Exception\ProxyClassesAlwaysRegenerating::create()`
* `invalidEntityRepository()` => `Exception\InvalidEntityRepository::fromClassName()`
* `missingIdentifierField()` => `Exception\MissingIdentifierField::fromFieldAndClass()`
* `unrecognizedIdentifierFields()` => `Exception\UnrecognizedIdentifierFields::fromClassAndFieldNames()`
* `cantUseInOperatorOnCompositeKeys()` => `Persisters\Exception\CantUseInOperatorOnCompositeKeys::create()`
## BC Break: `CacheException` is no longer a class, but an interface
All methods in `Doctrine\ORM\Cache\CacheException` have been extracted to dedicated exceptions.
* `updateReadOnlyCollection()` => `Cache\Exception\CannotUpdateReadOnlyCollection::fromEntityAndField()`
* `updateReadOnlyEntity()` => `Cache\Exception\CannotUpdateReadOnlyEntity::fromEntity()`
* `nonCacheableEntity()` => `Cache\Exception\NonCacheableEntity::fromEntity()`
* `nonCacheableEntityAssociation()` => `Cache\Exception\NonCacheableEntityAssociation::fromEntityAndField()`
## BC Break: Missing type declaration added for identifier generators
Although undocumented, it was possible to configure a custom repository
class that implements `ObjectRepository` but does not extend the
`EntityRepository` base class. Repository classes have to extend
`EntityRepository` now.
## BC BREAK: Removed support for entity namespace alias
- `EntityManager::getRepository()` no longer accepts the entity namespace alias
notation.
- `Configuration::addEntityNamespace()` and
`Configuration::getEntityNamespace()` have been removed.
## BC BREAK: Remove helper methods from `AbstractCollectionPersister`
The following protected methods of
`Doctrine\ORM\Cache\Persister\Collection\AbstractCollectionPersister`
have been removed.
* `evictCollectionCache()`
* `evictElementCache()`
## BC BREAK: `Doctrine\ORM\Query\TreeWalkerChainIterator`
This class has been removed without replacement.
## BC BREAK: Remove quoting methods from `ClassMetadata`
The following methods have been removed from the class metadata because
quoting is handled by implementations of `Doctrine\ORM\Mapping\QuoteStrategy`:
* `getQuotedIdentifierColumnNames()`
* `getQuotedColumnName()`
* `getQuotedTableName()`
* `getQuotedJoinTableName()`
## BC BREAK: Remove ability to merge detached entities
Merge semantics was a poor fit for the PHP "share-nothing" architecture.
In addition to that, merging caused multiple issues with data integrity
in the managed entity graph, which was constantly spawning more edge-case
bugs/scenarios.
The method `UnitOfWork::merge()` has been removed. The method
`EntityManager::merge()` will throw an exception on each call.
## BC BREAK: Removed ability to partially flush/commit entity manager and unit of work
The following methods don't accept a single entity or an array of entities anymore:
* `Doctrine\ORM\EntityManager::flush()`
* `Doctrine\ORM\Decorator\EntityManagerDecorator::flush()`
* `Doctrine\ORM\UnitOfWork::commit()`
The semantics of `flush()` and `commit()` will remain the same, but the change
tracking will be performed on all entities managed by the unit of work, and not
just on the provided entities, as the parameter is now completely ignored.
## BC BREAK: Removed ability to partially clear entity manager and unit of work
* Passing an argument other than `null` to `EntityManager::clear()` will raise
an exception.
* The unit of work cannot be cleared partially anymore. Passing an argument to
`UnitOfWork::clear()` does not have any effect anymore; the unit of work is
cleared completely.
* The method `EntityRepository::clear()` has been removed.
* The methods `getEntityClass()` and `clearsAllEntities()` have been removed
from `OnClearEventArgs`.
## BC BREAK: Remove support for Doctrine Cache
The Doctrine Cache library is not supported anymore. The following methods
have been removed from `Doctrine\ORM\Configuration`:
* `getQueryCacheImpl()`
* `setQueryCacheImpl()`
* `getHydrationCacheImpl()`
* `setHydrationCacheImpl()`
* `getMetadataCacheImpl()`
* `setMetadataCacheImpl()`
The methods have been replaced by PSR-6 compatible counterparts
(just strip the `Impl` suffix from the old name to get the new one).
## BC BREAK: Remove `Doctrine\ORM\Configuration::newDefaultAnnotationDriver`
This functionality has been moved to the new `ORMSetup` class. Call
`Doctrine\ORM\ORMSetup::createDefaultAnnotationDriver()` to create
a new annotation driver.
## BC BREAK: Remove `Doctrine\ORM\Tools\Setup`
In our effort to migrate from Doctrine Cache to PSR-6, the `Setup` class which
accepted a Doctrine Cache instance in each method has been removed.
The replacement is `Doctrine\ORM\ORMSetup` which accepts a PSR-6
cache instead.
## BC BREAK: Removed named queries
All APIs related to named queries have been removed.
## BC BREAK: Remove old cache accessors and mutators from query classes
The following methods have been removed from `AbstractQuery`:
* `setResultCacheDriver()`
* `getResultCacheDriver()`
* `useResultCache()`
* `getResultCacheLifetime()`
* `getResultCacheId()`
The following methods have been removed from `Query`:
* `setQueryCacheDriver()`
* `getQueryCacheDriver()`
## BC BREAK: Remove `Doctrine\ORM\Cache\MultiGetRegion`
The interface has been merged into `Doctrine\ORM\Cache\Region`.
## BC BREAK: Rename `AbstractIdGenerator::generate()` to `generateId()`
* Implementations of `AbstractIdGenerator` have to implement the method
`generateId()`.
* The method `generate()` has been removed from `AbstractIdGenerator`.
## BC BREAK: Remove cache settings inspection
Doctrine does not provide its own cache implementation anymore and relies on
the PSR-6 standard instead. As a consequence, we cannot determine anymore
whether a given cache adapter is suitable for a production environment.
Because of that, functionality that aims to do so has been removed:
* `Configuration::ensureProductionSettings()`
* the `orm:ensure-production-settings` console command
## BC BREAK: PSR-6-based second level cache
The second level cache has been reworked to consume a PSR-6 cache. Using a
Doctrine Cache instance is not supported anymore.
* `DefaultCacheFactory`: The constructor expects a PSR-6 cache item pool as
second argument now.
* `DefaultMultiGetRegion`: This class has been removed.
* `DefaultRegion`:
* The constructor expects a PSR-6 cache item pool as second argument now.
* The protected `$cache` property is removed.
* The properties `$name` and `$lifetime` as well as the constant
`REGION_KEY_SEPARATOR` and the method `getCacheEntryKey()` are
`private` now.
* The method `getCache()` has been removed.
## BC Break: Remove `Doctrine\ORM\Mapping\Driver\PHPDriver`
Use `StaticPHPDriver` instead when you want to programmatically configure
entity metadata.
## BC BREAK: Remove `Doctrine\ORM\EntityManagerInterface#transactional()`
This method has been replaced by `Doctrine\ORM\EntityManagerInterface#wrapInTransaction()`.
## BC BREAK: Removed support for schema emulation.
The ORM no longer attempts to emulate schemas on SQLite.
## BC BREAK: Remove `Setup::registerAutoloadDirectory()`
Use Composer's autoloader instead.
## BC BREAK: Remove YAML mapping drivers.
If your code relies on `YamlDriver` or `SimpleYamlDriver`, you **MUST** migrate to
attribute, annotation or XML drivers instead.
You can use the `orm:convert-mapping` command to convert your metadata mapping to XML
_before_ upgrading to 3.0:
```sh
php doctrine orm:convert-mapping xml /path/to/mapping-path-converted-to-xml
```
## BC BREAK: Remove code generators and related console commands
These console commands have been removed:
* `orm:convert-d1-schema`
* `orm:convert-mapping`
* `orm:generate:entities`
* `orm:generate-repositories`
These classes have been deprecated:
* `Doctrine\ORM\Tools\ConvertDoctrine1Schema`
* `Doctrine\ORM\Tools\EntityGenerator`
* `Doctrine\ORM\Tools\EntityRepositoryGenerator`
The entire `Doctrine\ORM\Tools\Export` namespace has been removed as well.
## BC BREAK: Removed `Doctrine\ORM\Version`
Use Composer's runtime API if you _really_ need to check the version of the ORM package at runtime.
## BC BREAK: EntityRepository::count() signature change
The argument `$criteria` of `Doctrine\ORM\EntityRepository::count()` is now
optional. Overrides in child classes should be made compatible.
## BC BREAK: changes in exception hierarchy
- `Doctrine\ORM\ORMException` has been removed
- `Doctrine\ORM\Exception\ORMException` is now an interface
## Variadic methods now use native variadics
The following methods were using `func_get_args()` to simulate a variadic argument:
- `Doctrine\ORM\Query\Expr#andX()`
- `Doctrine\ORM\Query\Expr#orX()`
- `Doctrine\ORM\QueryBuilder#select()`
- `Doctrine\ORM\QueryBuilder#addSelect()`
- `Doctrine\ORM\QueryBuilder#where()`
- `Doctrine\ORM\QueryBuilder#andWhere()`
- `Doctrine\ORM\QueryBuilder#orWhere()`
- `Doctrine\ORM\QueryBuilder#groupBy()`
- `Doctrine\ORM\QueryBuilder#andGroupBy()`
- `Doctrine\ORM\QueryBuilder#having()`
- `Doctrine\ORM\QueryBuilder#andHaving()`
- `Doctrine\ORM\QueryBuilder#orHaving()`
A variadic argument is now actually used in their signatures signature (`...$x`).
Signatures of overridden methods should be changed accordingly
## Minor BC BREAK: removed `Doctrine\ORM\EntityManagerInterface#copy()`
Method `Doctrine\ORM\EntityManagerInterface#copy()` never got its implementation and is removed in 3.0.
## BC BREAK: Removed classes related to UUID and TABLE generator strategies
The following classes have been removed:
- `Doctrine\ORM\Id\TableGenerator`
- `Doctrine\ORM\Id\UuidGenerator`
Using the `UUID` strategy for generating identifiers is not supported anymore.
## BC BREAK: Removed `Query::iterate()`
The deprecated method `Query::iterate()` has been removed along with the
following classes and methods:
- `AbstractHydrator::iterate()`
- `AbstractHydrator::hydrateRow()`
- `IterableResult`
Use `toIterable()` instead.
# Upgrade to 2.19
## Deprecate calling `ClassMetadata::getAssociationMappedByTargetField()` with the owning side of an association
Calling
`Doctrine\ORM\Mapping\ClassMetadata::getAssociationMappedByTargetField()` with
the owning side of an association returns `null`, which is undocumented, and
wrong according to the phpdoc of the parent method.
If you do not know whether you are on the owning or inverse side of an association,
you can use `Doctrine\ORM\Mapping\ClassMetadata::isAssociationInverseSide()`
to find out.
## Deprecate `Doctrine\ORM\Query\Lexer::T_*` constants
Use `Doctrine\ORM\Query\TokenType::T_*` instead.
# Upgrade to 2.17
## Deprecate annotations classes for named queries
The following classes have been deprecated:
* `Doctrine\ORM\Mapping\NamedNativeQueries`
* `Doctrine\ORM\Mapping\NamedNativeQuery`
* `Doctrine\ORM\Mapping\NamedQueries`
* `Doctrine\ORM\Mapping\NamedQuery`
## Deprecate `Doctrine\ORM\Query\Exec\AbstractSqlExecutor::_sqlStatements`
Use `Doctrine\ORM\Query\Exec\AbstractSqlExecutor::sqlStatements` instead.
## Undeprecate `Doctrine\ORM\Proxy\Autoloader`
It will be a full-fledged class, no longer extending
`Doctrine\Common\Proxy\Autoloader` in 3.0.x.
## Deprecated: reliance on the non-optimal defaults that come with the `AUTO` identifier generation strategy
When the `AUTO` identifier generation strategy was introduced, the best
strategy at the time was selected for each database platform.
A lot of time has passed since then, and with ORM 3.0.0 and DBAL 4.0.0, support
for better strategies will be added.
Because of that, it is now deprecated to rely on the historical defaults when
they differ from what we will be recommended in the future.
Instead, you should pick a strategy for each database platform you use, and it
will be used when using `AUTO`. As of now, only PostgreSQL is affected by this.
It is recommended that PostgreSQL users configure their existing and new
applications to use `SEQUENCE` until `doctrine/dbal` 4.0.0 is released:
```php
use Doctrine\DBAL\Platforms\PostgreSQLPlatform;
use Doctrine\ORM\Configuration;
assert($configuration instanceof Configuration);
$configuration->setIdentityGenerationPreferences([
PostgreSQLPlatform::CLASS => ClassMetadata::GENERATOR_TYPE_SEQUENCE,
]);
```
When DBAL 4 is released, `AUTO` will result in `IDENTITY`, and the above
configuration should be removed to migrate to it.
## Deprecate `EntityManagerInterface::getPartialReference()`
This method does not have a replacement and will be removed in 3.0.
## Deprecate not-enabling lazy-ghosts
Not enabling lazy ghost objects is deprecated. In ORM 3.0, they will be always enabled.
Ensure `Doctrine\ORM\Configuration::setLazyGhostObjectEnabled(true)` is called to enable them.
# Upgrade to 2.16
## Deprecated accepting duplicate IDs in the identity map
For any given entity class and ID value, there should be only one object instance
representing the entity.
In https://github.com/doctrine/orm/pull/10785, a check was added that will guard this
in the identity map. The most probable cause for violations of this rule are collisions
of application-provided IDs.
In ORM 2.16.0, the check was added by throwing an exception. In ORM 2.16.1, this will be
changed to a deprecation notice. ORM 3.0 will make it an exception again. Use
`\Doctrine\ORM\Configuration::setRejectIdCollisionInIdentityMap()` if you want to opt-in
to the new mode.
## Potential changes to the order in which `INSERT`s are executed
In https://github.com/doctrine/orm/pull/10547, the commit order computation was improved
to fix a series of bugs where a correct (working) commit order was previously not found.
Also, the new computation may get away with fewer queries being executed: By inserting
referred-to entities first and using their ID values for foreign key fields in subsequent
`INSERT` statements, additional `UPDATE` statements that were previously necessary can be
avoided.
When using database-provided, auto-incrementing IDs, this may lead to IDs being assigned
to entities in a different order than it was previously the case.
## Deprecated returning post insert IDs from `EntityPersister::executeInserts()`
Persisters implementing `\Doctrine\ORM\Persisters\Entity\EntityPersister` should no longer
return an array of post insert IDs from their `::executeInserts()` method. Make the
persister call `Doctrine\ORM\UnitOfWork::assignPostInsertId()` instead.
## Changing the way how reflection-based mapping drivers report fields, deprecated the "old" mode
In ORM 3.0, a change will be made regarding how the `AttributeDriver` reports field mappings.
This change is necessary to be able to detect (and reject) some invalid mapping configurations.
To avoid surprises during 2.x upgrades, the new mode is opt-in. It can be activated on the
`AttributeDriver` and `AnnotationDriver` by setting the `$reportFieldsWhereDeclared`
constructor parameter to `true`. It will cause `MappingException`s to be thrown when invalid
configurations are detected.
Not enabling the new mode will cause a deprecation notice to be raised. In ORM 3.0,
only the new mode will be available.
# Upgrade to 2.15
## Deprecated configuring `JoinColumn` on the inverse side of one-to-one associations
For one-to-one associations, the side using the `mappedBy` attribute is the inverse side.
The owning side is the entity with the table containing the foreign key. Using `JoinColumn`
configuration on the _inverse_ side now triggers a deprecation notice and will be an error
in 3.0.
## Deprecated overriding fields or associations not declared in mapped superclasses
As stated in the documentation, fields and associations may only be overridden when being inherited
from mapped superclasses. Overriding them for parent entity classes now triggers a deprecation notice
and will be an error in 3.0.
## Deprecated undeclared entity inheritance
As soon as an entity class inherits from another entity class, inheritance has to
be declared by adding the appropriate configuration for the root entity.
## Deprecated stubs for "concrete table inheritance"
This third way of mapping class inheritance was never implemented. Code stubs are
now deprecated and will be removed in 3.0.
* `\Doctrine\ORM\Mapping\ClassMetadataInfo::INHERITANCE_TYPE_TABLE_PER_CLASS` constant
* `\Doctrine\ORM\Mapping\ClassMetadataInfo::isInheritanceTypeTablePerClass()` method
* Using `TABLE_PER_CLASS` as the value for the `InheritanceType` attribute or annotation
or in XML configuration files.
# Upgrade to 2.14
## Deprecated `Doctrine\ORM\Persisters\Exception\UnrecognizedField::byName($field)` method.
Use `Doctrine\ORM\Persisters\Exception\UnrecognizedField::byFullyQualifiedName($className, $field)` instead.
## Deprecated constants of `Doctrine\ORM\Internal\CommitOrderCalculator`
The following public constants have been deprecated:
* `CommitOrderCalculator::NOT_VISITED`
* `CommitOrderCalculator::IN_PROGRESS`
* `CommitOrderCalculator::VISITED`
These constants were used for internal purposes. Relying on them is discouraged.
## Deprecated `Doctrine\ORM\Query\AST\InExpression`
The AST parser will create a `InListExpression` or a `InSubselectExpression` when
encountering an `IN ()` DQL expression instead of a generic `InExpression`.
As a consequence, `SqlWalker::walkInExpression()` has been deprecated in favor of
`SqlWalker::walkInListExpression()` and `SqlWalker::walkInSubselectExpression()`.
## Deprecated constructing a `CacheKey` without `$hash`
The `Doctrine\ORM\Cache\CacheKey` class has an explicit constructor now with
an optional parameter `$hash`. That parameter will become mandatory in 3.0.
## Deprecated `AttributeDriver::$entityAnnotationClasses`
If you need to change the behavior of `AttributeDriver::isTransient()`,
override that method instead.
## Deprecated incomplete schema updates
Using `orm:schema-tool:update` without passing the `--complete` flag is
deprecated. Use schema asset filtering if you need to preserve assets not
managed by DBAL.
Likewise, calling `SchemaTool::updateSchema()` or
`SchemaTool::getUpdateSchemaSql()` with a second argument is deprecated.
## Deprecated annotation mapping driver.
Please switch to one of the other mapping drivers. Native attributes which PHP
supports since version 8.0 are probably your best option.
As a consequence, the following methods are deprecated:
- `ORMSetup::createAnnotationMetadataConfiguration`
- `ORMSetup::createDefaultAnnotationDriver`
The marker interface `Doctrine\ORM\Mapping\Annotation` is deprecated as well.
All annotation/attribute classes implement
`Doctrine\ORM\Mapping\MappingAttribute` now.
## Deprecated `Doctrine\ORM\Proxy\Proxy` interface.
Use `Doctrine\Persistence\Proxy` instead to check whether proxies are initialized.
## Deprecated `Doctrine\ORM\Event\LifecycleEventArgs` class.
It will be removed in 3.0. Use one of the dedicated event classes instead:
* `Doctrine\ORM\Event\PrePersistEventArgs`
* `Doctrine\ORM\Event\PreUpdateEventArgs`
* `Doctrine\ORM\Event\PreRemoveEventArgs`
* `Doctrine\ORM\Event\PostPersistEventArgs`
* `Doctrine\ORM\Event\PostUpdateEventArgs`
* `Doctrine\ORM\Event\PostRemoveEventArgs`
* `Doctrine\ORM\Event\PostLoadEventArgs`
# Upgrade to 2.13
## Deprecated `EntityManager::create()`
The constructor of `EntityManager` is now public and should be used instead of the `create()` method.
However, the constructor expects a `Connection` while `create()` accepted an array with connection parameters.
You can pass that array to DBAL's `Doctrine\DBAL\DriverManager::getConnection()` method to bootstrap the
connection.
## Deprecated `QueryBuilder` methods and constants.
1. The `QueryBuilder::getState()` method has been deprecated as the builder state is an internal concern.
2. Relying on the type of the query being built by using `QueryBuilder::getType()` has been deprecated.
If necessary, track the type of the query being built outside of the builder.
The following `QueryBuilder` constants related to the above methods have been deprecated:
1. `SELECT`,
2. `DELETE`,
3. `UPDATE`,
4. `STATE_DIRTY`,
5. `STATE_CLEAN`.
## Deprecated omitting only the alias argument for `QueryBuilder::update` and `QueryBuilder::delete`
When building an UPDATE or DELETE query and when passing a class/type to the function, the alias argument must not be omitted.
### Before
```php
$qb = $em->createQueryBuilder()
->delete('User u')
->where('u.id = :user_id')
->setParameter('user_id', 1);
```
### After
```php
$qb = $em->createQueryBuilder()
->delete('User', 'u')
->where('u.id = :user_id')
->setParameter('user_id', 1);
```
## Deprecated using the `IDENTITY` identifier strategy on platform that do not support identity columns
If identity columns are emulated with sequences on the platform you are using,
you should switch to the `SEQUENCE` strategy.
## Deprecated passing `null` to `Doctrine\ORM\Query::setFirstResult()`
`$query->setFirstResult(null);` is equivalent to `$query->setFirstResult(0)`.
## Deprecated calling setters without arguments
The following methods will require an argument in 3.0. Pass `null` instead of
omitting the argument.
* `Doctrine\ORM\Event\OnClassMetadataNotFoundEventArgs::setFoundMetadata()`
* `Doctrine\ORM\AbstractQuery::setHydrationCacheProfile()`
* `Doctrine\ORM\AbstractQuery::setResultCache()`
* `Doctrine\ORM\AbstractQuery::setResultCacheProfile()`
## Deprecated passing invalid fetch modes to `AbstractQuery::setFetchMode()`
Calling `AbstractQuery::setFetchMode()` with anything else than
`Doctrine\ORM\Mapping::FETCH_EAGER` results in
`Doctrine\ORM\Mapping::FETCH_LAZY` being used. Relying on that behavior is
deprecated and will result in an exception in 3.0.
## Deprecated `getEntityManager()` in `Doctrine\ORM\Event\OnClearEventArgs` and `Doctrine\ORM\Event\*FlushEventArgs`
This method has been deprecated in:
* `Doctrine\ORM\Event\OnClearEventArgs`
* `Doctrine\ORM\Event\OnFlushEventArgs`
* `Doctrine\ORM\Event\PostFlushEventArgs`
* `Doctrine\ORM\Event\PreFlushEventArgs`
It will be removed in 3.0. Use `getObjectManager()` instead.
## Prepare split of output walkers and tree walkers
In 3.0, `SqlWalker` and its child classes won't implement the `TreeWalker`
interface anymore. Relying on that inheritance is deprecated.
The following methods of the `TreeWalker` interface have been deprecated:
* `setQueryComponent()`
* `walkSelectClause()`
* `walkFromClause()`
* `walkFunction()`
* `walkOrderByClause()`
* `walkOrderByItem()`
* `walkHavingClause()`
* `walkJoin()`
* `walkSelectExpression()`
* `walkQuantifiedExpression()`
* `walkSubselect()`
* `walkSubselectFromClause()`
* `walkSimpleSelectClause()`
* `walkSimpleSelectExpression()`
* `walkAggregateExpression()`
* `walkGroupByClause()`
* `walkGroupByItem()`
* `walkDeleteClause()`
* `walkUpdateClause()`
* `walkUpdateItem()`
* `walkWhereClause()`
* `walkConditionalExpression()`
* `walkConditionalTerm()`
* `walkConditionalFactor()`
* `walkConditionalPrimary()`
* `walkExistsExpression()`
* `walkCollectionMemberExpression()`
* `walkEmptyCollectionComparisonExpression()`
* `walkNullComparisonExpression()`
* `walkInExpression()`
* `walkInstanceOfExpression()`
* `walkLiteral()`
* `walkBetweenExpression()`
* `walkLikeExpression()`
* `walkStateFieldPathExpression()`
* `walkComparisonExpression()`
* `walkInputParameter()`
* `walkArithmeticExpression()`
* `walkArithmeticTerm()`
* `walkStringPrimary()`
* `walkArithmeticFactor()`
* `walkSimpleArithmeticExpression()`
* `walkPathExpression()`
* `walkResultVariable()`
* `getExecutor()`
The following changes have been made to the abstract `TreeWalkerAdapter` class:
* All implementations of now-deprecated `TreeWalker` methods have been
deprecated as well.
* The method `setQueryComponent()` will become protected in 3.0. Calling it
publicly is deprecated.
* The method `_getQueryComponents()` is deprecated, call `getQueryComponents()`
instead.
On the `TreeWalkerChain` class, all implementations of now-deprecated
`TreeWalker` methods have been deprecated as well. However, `SqlWalker` is
unaffected by those deprecations and will continue to implement all of those
methods.
## Deprecated passing `null` to `Doctrine\ORM\Query::setDQL()`
Doing `$query->setDQL(null);` achieves nothing.
## Deprecated omitting second argument to `NamingStrategy::joinColumnName`
When implementing `NamingStrategy`, it is deprecated to implement
`joinColumnName()` with only one argument.
### Before
```php
<?php
class MyStrategy implements NamingStrategy
{
/**
* @param string $propertyName A property name.
*/
public function joinColumnName($propertyName): string
{
// …
}
}
```
### After
For backward-compatibility reasons, the parameter has to be optional, but can
be documented as guaranteed to be a `class-string`.
```php
<?php
class MyStrategy implements NamingStrategy
{
/**
* @param string $propertyName A property name.
* @param class-string $className
*/
public function joinColumnName($propertyName, $className = null): string
{
// …
}
}
```
## Deprecated methods related to named queries
The following methods have been deprecated:
- `Doctrine\ORM\Query\ResultSetMappingBuilder::addNamedNativeQueryMapping()`
- `Doctrine\ORM\Query\ResultSetMappingBuilder::addNamedNativeQueryResultClassMapping()`
- `Doctrine\ORM\Query\ResultSetMappingBuilder::addNamedNativeQueryResultSetMapping()`
- `Doctrine\ORM\Query\ResultSetMappingBuilder::addNamedNativeQueryEntityResultMapping()`
## Deprecated classes related to Doctrine 1 and reverse engineering
The following classes have been deprecated:
- `Doctrine\ORM\Tools\ConvertDoctrine1Schema`
- `Doctrine\ORM\Tools\DisconnectedClassMetadataFactory`
## Deprecate `ClassMetadataInfo` usage
It is deprecated to pass `Doctrine\ORM\Mapping\ClassMetadataInfo` instances
that are not also instances of `Doctrine\ORM\ClassMetadata` to the following
methods:
- `Doctrine\ORM\Mapping\Builder\ClassMetadataBuilder::__construct()`
- `Doctrine\ORM\Mapping\Driver\DatabaseDriver::loadMetadataForClass()`
- `Doctrine\ORM\Tools\SchemaValidator::validateClass()`
# Upgrade to 2.12
## Deprecated the `doctrine` binary.
The documentation explains how the console tools can be bootstrapped for
standalone usage.
The method `ConsoleRunner::printCliConfigTemplate()` is deprecated because it
was only useful in the context of the `doctrine` binary.
## Deprecate omitting `$class` argument to `ORMInvalidArgumentException::invalidIdentifierBindingEntity()`
To make it easier to identify understand the cause for that exception, it is
deprecated to omit the class name when calling
`ORMInvalidArgumentException::invalidIdentifierBindingEntity()`.
## Deprecate `Doctrine\ORM\Tools\Console\Helper\EntityManagerHelper`
Using a console helper to provide the ORM's console commands with one or
multiple entity managers had been deprecated with 2.9 already. This leaves
The `EntityManagerHelper` class with no purpose which is why it is now
deprecated too. Applications that still rely on the `em` console helper, can
easily recreate that class in their own codebase.
## Deprecate custom repository classes that don't extend `EntityRepository`
Although undocumented, it is currently possible to configure a custom repository
class that implements `ObjectRepository` but does not extend the
`EntityRepository` base class.
This is now deprecated. Please extend `EntityRepository` instead.
## Deprecated more APIs related to entity namespace aliases
```diff
-$config = $entityManager->getConfiguration();
-$config->addEntityNamespace('CMS', 'My\App\Cms');
+use My\App\Cms\CmsUser;
-$entityManager->getRepository('CMS:CmsUser');
+$entityManager->getRepository(CmsUser::class);
```
## Deprecate `AttributeDriver::getReader()` and `AnnotationDriver::getReader()`
That method was inherited from the abstract `AnnotationDriver` class of
`doctrine/persistence`, and does not seem to serve any purpose.
## Un-deprecate `Doctrine\ORM\Proxy\Proxy`
Because no forward-compatible new proxy solution had been implemented yet, the
current proxy mechanism is not considered deprecated anymore for the time
being. This applies to the following interfaces/classes:
* `Doctrine\ORM\Proxy\Proxy`
* `Doctrine\ORM\Proxy\ProxyFactory`
These methods have been un-deprecated:
* `Doctrine\ORM\Configuration::getAutoGenerateProxyClasses()`
* `Doctrine\ORM\Configuration::getProxyDir()`
* `Doctrine\ORM\Configuration::getProxyNamespace()`
Note that the `Doctrine\ORM\Proxy\Autoloader` remains deprecated and will be removed in 3.0.
## Deprecate helper methods from `AbstractCollectionPersister`
The following protected methods of
`Doctrine\ORM\Cache\Persister\Collection\AbstractCollectionPersister`
are not in use anymore and will be removed.
* `evictCollectionCache()`
* `evictElementCache()`
## Deprecate `Doctrine\ORM\Query\TreeWalkerChainIterator`
This class won't have a replacement.
## Deprecate `OnClearEventArgs::getEntityClass()` and `OnClearEventArgs::clearsAllEntities()`
These methods will be removed in 3.0 along with the ability to partially clear
the entity manager.
## Deprecate `Doctrine\ORM\Configuration::newDefaultAnnotationDriver`
This functionality has been moved to the new `ORMSetup` class. Call
`Doctrine\ORM\ORMSetup::createDefaultAnnotationDriver()` to create
a new annotation driver.
## Deprecate `Doctrine\ORM\Tools\Setup`
In our effort to migrate from Doctrine Cache to PSR-6, the `Setup` class which
accepted a Doctrine Cache instance in each method has been deprecated.
The replacement is `Doctrine\ORM\ORMSetup` which accepts a PSR-6
cache instead.
## Deprecate `Doctrine\ORM\Cache\MultiGetRegion`
The interface will be merged with `Doctrine\ORM\Cache\Region` in 3.0.
# Upgrade to 2.11
## Rename `AbstractIdGenerator::generate()` to `generateId()`
Implementations of `AbstractIdGenerator` have to override the method
`generateId()` without calling the parent implementation. Not doing so is
deprecated. Calling `generate()` on any `AbstractIdGenerator` implementation
is deprecated.
## PSR-6-based second level cache
The second level cache has been reworked to consume a PSR-6 cache. Using a
Doctrine Cache instance is deprecated.
* `DefaultCacheFactory`: The constructor expects a PSR-6 cache item pool as
second argument now.
* `DefaultMultiGetRegion`: This class is deprecated in favor of `DefaultRegion`.
* `DefaultRegion`:
* The constructor expects a PSR-6 cache item pool as second argument now.
* The protected `$cache` property is deprecated.
* The properties `$name` and `$lifetime` as well as the constant
`REGION_KEY_SEPARATOR` and the method `getCacheEntryKey()` are flagged as
`@internal` now. They all will become `private` in 3.0.
* The method `getCache()` is deprecated without replacement.
## Deprecated: `Doctrine\ORM\Mapping\Driver\PHPDriver`
Use `StaticPHPDriver` instead when you want to programmatically configure
entity metadata.
You can convert mappings with the `orm:convert-mapping` command or more simply
in this case, `include` the metadata file from the `loadMetadata` static method
used by the `StaticPHPDriver`.
## Deprecated: `Setup::registerAutoloadDirectory()`
Use Composer's autoloader instead.
## Deprecated: `AbstractHydrator::hydrateRow()`
Following the deprecation of the method `AbstractHydrator::iterate()`, the
method `hydrateRow()` has been deprecated as well.
## Deprecate cache settings inspection
Doctrine does not provide its own cache implementation anymore and relies on
the PSR-6 standard instead. As a consequence, we cannot determine anymore
whether a given cache adapter is suitable for a production environment.
Because of that, functionality that aims to do so has been deprecated:
* `Configuration::ensureProductionSettings()`
* the `orm:ensure-production-settings` console command
# Upgrade to 2.10
## BC Break: `UnitOfWork` now relies on SPL object IDs, not hashes
When calling the following methods, you are now supposed to use the result of
`spl_object_id()`, and not `spl_object_hash()`:
- `UnitOfWork::clearEntityChangeSet()`
- `UnitOfWork::setOriginalEntityProperty()`
## BC Break: Removed `TABLE` id generator strategy
The implementation was unfinished for 14 years.
It is now deprecated to rely on:
- `Doctrine\ORM\Id\TableGenerator`;
- `Doctrine\ORM\Mapping\ClassMetadata::GENERATOR_TYPE_TABLE`;
- `Doctrine\ORM\Mapping\ClassMetadata::$tableGeneratorDefinition`;
- or `Doctrine\ORM\Mapping\ClassMetadata::isIdGeneratorTable()`.
## New method `Doctrine\ORM\EntityManagerInterface#wrapInTransaction($func)`
Works the same as `Doctrine\ORM\EntityManagerInterface#transactional()` but returns any value returned from `$func` closure rather than just _non-empty value returned from the closure or true_.
Because of BC policy, the method does not exist on the interface yet. This is the example of safe usage:
```php
function foo(EntityManagerInterface $entityManager, callable $func) {
if (method_exists($entityManager, 'wrapInTransaction')) {
return $entityManager->wrapInTransaction($func);
}
return $entityManager->transactional($func);
}
```
`Doctrine\ORM\EntityManagerInterface#transactional()` has been deprecated.
## Minor BC BREAK: some exception methods have been removed
The following methods were not in use and are very unlikely to be used by
downstream packages or applications, and were consequently removed:
- `ORMException::entityMissingForeignAssignedId`
- `ORMException::entityMissingAssignedIdForField`
- `ORMException::invalidFlushMode`
## Deprecated: database-side UUID generation
[DB-generated UUIDs are deprecated as of `doctrine/dbal` 2.8][DBAL deprecation].
As a consequence, using the `UUID` strategy for generating identifiers is deprecated as well.
Furthermore, relying on the following classes and methods is deprecated:
- `Doctrine\ORM\Id\UuidGenerator`
- `Doctrine\ORM\Mapping\ClassMetadataInfo::isIdentifierUuid()`
[DBAL deprecation]: https://github.com/doctrine/dbal/pull/3212
## Minor BC BREAK: Custom hydrators and `toIterable()`
The type declaration of the `$stmt` parameter of `AbstractHydrator::toIterable()` has been removed. This change might
break custom hydrator implementations that override this very method.
Overriding this method is not recommended, which is why the method is documented as `@final` now.
```diff
- public function toIterable(ResultStatement $stmt, ResultSetMapping $resultSetMapping, array $hints = []): iterable
+ public function toIterable($stmt, ResultSetMapping $resultSetMapping, array $hints = []): iterable
```
## Deprecated: Entity Namespace Aliases
Entity namespace aliases are deprecated, use the magic ::class constant to abbreviate full class names
in EntityManager, EntityRepository and DQL.
```diff
- $entityManager->find('MyBundle:User', $id);
+ $entityManager->find(User::class, $id);
```
# Upgrade to 2.9
## Minor BC BREAK: Setup tool needs cache implementation
With the deprecation of doctrine/cache, the setup tool might no longer work as expected without a different cache
implementation. To work around this:
* Install symfony/cache: `composer require symfony/cache`. This will keep previous behaviour without any changes
* Instantiate caches yourself: to use a different cache implementation, pass a cache instance when calling any
configuration factory in the setup tool:
```diff
- $config = Setup::createAnnotationMetadataConfiguration($paths, $isDevMode, $proxyDir);
+ $cache = \Doctrine\Common\Cache\Psr6\DoctrineProvider::wrap($anyPsr6Implementation);
+ $config = Setup::createAnnotationMetadataConfiguration($paths, $isDevMode, $proxyDir, $cache);
```
* As a quick workaround, you can lock the doctrine/cache dependency to work around this: `composer require doctrine/cache ^1.11`.
Note that this is only recommended as a bandaid fix, as future versions of ORM will no longer work with doctrine/cache
1.11.
## Deprecated: doctrine/cache for metadata caching
The `Doctrine\ORM\Configuration#setMetadataCacheImpl()` method is deprecated and should no longer be used. Please use
`Doctrine\ORM\Configuration#setMetadataCache()` with any PSR-6 cache adapter instead.
## Removed: flushing metadata cache
To support PSR-6 caches, the `--flush` option for the `orm:clear-cache:metadata` command is ignored. Metadata cache is
now always cleared regardless of the cache adapter being used.
# Upgrade to 2.8
## Minor BC BREAK: Failed commit now throw OptimisticLockException
Method `Doctrine\ORM\UnitOfWork#commit()` can throw an OptimisticLockException when a commit silently fails and returns false
since `Doctrine\DBAL\Connection#commit()` signature changed from returning void to boolean
## Deprecated: `Doctrine\ORM\AbstractQuery#iterate()`
The method `Doctrine\ORM\AbstractQuery#iterate()` is deprecated in favor of `Doctrine\ORM\AbstractQuery#toIterable()`.
Note that `toIterable()` yields results of the query, unlike `iterate()` which yielded each result wrapped into an array.
# Upgrade to 2.7
## Added `Doctrine\ORM\AbstractQuery#enableResultCache()` and `Doctrine\ORM\AbstractQuery#disableResultCache()` methods
Method `Doctrine\ORM\AbstractQuery#useResultCache()` which could be used for both enabling and disabling the cache
(depending on passed flag) was split into two.
## Minor BC BREAK: paginator output walkers aren't be called anymore on sub-queries for queries without max results
To optimize DB interaction, `Doctrine\ORM\Tools\Pagination\Paginator` no longer fetches identifiers to be able to
perform the pagination with join collections when max results isn't set in the query.
## Minor BC BREAK: tables filtered with `schema_filter` are no longer created
When generating schema diffs, if a source table is filtered out by a `schema_filter` expression, then a `CREATE TABLE` was
always generated, even if the table already existed. This has been changed in this release and the table will no longer
be created.
## Deprecated number unaware `Doctrine\ORM\Mapping\UnderscoreNamingStrategy`
In the last patch of the `v2.6.x` series, we fixed a bug that was not converting names properly when they had numbers
(e.g.: `base64Encoded` was wrongly converted to `base64encoded` instead of `base64_encoded`).
In order to not break BC we've introduced a way to enable the fixed behavior using a boolean constructor argument. This
argument will be removed in 3.0 and the default behavior will be the fixed one.
## Deprecated: `Doctrine\ORM\AbstractQuery#useResultCache()`
Method `Doctrine\ORM\AbstractQuery#useResultCache()` is deprecated because it is split into `enableResultCache()`
and `disableResultCache()`. It will be removed in 3.0.
## Deprecated code generators and related console commands
These console commands have been deprecated:
* `orm:convert-mapping`
* `orm:generate:entities`
* `orm:generate-repositories`
These classes have been deprecated:
* `Doctrine\ORM\Tools\EntityGenerator`
* `Doctrine\ORM\Tools\EntityRepositoryGenerator`
Whole Doctrine\ORM\Tools\Export namespace with all its members have been deprecated as well.
## Deprecated `Doctrine\ORM\Proxy\Proxy` marker interface
Proxy objects in Doctrine ORM 3.0 will no longer implement `Doctrine\ORM\Proxy\Proxy` nor
`Doctrine\Persistence\Proxy`: instead, they implement
`ProxyManager\Proxy\GhostObjectInterface`.
These related classes have been deprecated:
* `Doctrine\ORM\Proxy\ProxyFactory`
* `Doctrine\ORM\Proxy\Autoloader` - we suggest using the composer autoloader instead
These methods have been deprecated:
* `Doctrine\ORM\Configuration#getAutoGenerateProxyClasses()`
* `Doctrine\ORM\Configuration#getProxyDir()`
* `Doctrine\ORM\Configuration#getProxyNamespace()`
## Deprecated `Doctrine\ORM\Version`
The `Doctrine\ORM\Version` class is now deprecated and will be removed in Doctrine ORM 3.0:
please refrain from checking the ORM version at runtime or use Composer's [runtime API](https://getcomposer.org/doc/07-runtime.md#knowing-whether-package-x-is-installed-in-version-y).
## Deprecated `EntityManager#merge()` method
Merge semantics was a poor fit for the PHP "share-nothing" architecture.
In addition to that, merging caused multiple issues with data integrity
in the managed entity graph, which was constantly spawning more edge-case bugs/scenarios.
The following API methods were therefore deprecated:
* `EntityManager#merge()`
* `UnitOfWork#merge()`
An alternative to `EntityManager#merge()` will not be provided by ORM 3.0, since the merging
semantics should be part of the business domain rather than the persistence domain of an
application. If your application relies heavily on CRUD-alike interactions and/or `PATCH`
restful operations, you should look at alternatives such as [JMSSerializer](https://github.com/schmittjoh/serializer).
## Extending `EntityManager` is deprecated
Final keyword will be added to the `EntityManager::class` in Doctrine ORM 3.0 in order to ensure that EntityManager
is not used as valid extension point. Valid extension point should be EntityManagerInterface.
## Deprecated `EntityManager#clear($entityName)`
If your code relies on clearing a single entity type via `EntityManager#clear($entityName)`,
the signature has been changed to `EntityManager#clear()`.
The main reason is that partial clears caused multiple issues with data integrity
in the managed entity graph, which was constantly spawning more edge-case bugs/scenarios.
## Deprecated `EntityManager#flush($entity)` and `EntityManager#flush($entities)`
If your code relies on single entity flushing optimisations via
`EntityManager#flush($entity)`, the signature has been changed to
`EntityManager#flush()`.
Said API was affected by multiple data integrity bugs due to the fact
that change tracking was being restricted upon a subset of the managed
entities. The ORM cannot support committing subsets of the managed
entities while also guaranteeing data integrity, therefore this
utility was removed.
The `flush()` semantics will remain the same, but the change tracking will be performed
on all entities managed by the unit of work, and not just on the provided
`$entity` or `$entities`, as the parameter is now completely ignored.
The same applies to `UnitOfWork#commit($entity)`, which will simply be
`UnitOfWork#commit()`.
If you would still like to perform batching operations over small `UnitOfWork`
instances, it is suggested to follow these paths instead:
* eagerly use `EntityManager#clear()` in conjunction with a specific second level
cache configuration (see http://docs.doctrine-project.org/projects/doctrine-orm/en/stable/reference/second-level-cache.html)
* use an explicit change tracking policy (see http://docs.doctrine-project.org/projects/doctrine-orm/en/stable/reference/change-tracking-policies.html)
## Deprecated `YAML` mapping drivers.
If your code relies on `YamlDriver` or `SimpleYamlDriver`, you **MUST** change to
annotation or XML drivers instead.
## Deprecated: `Doctrine\ORM\EntityManagerInterface#copy()`
Method `Doctrine\ORM\EntityManagerInterface#copy()` never got its implementation and is deprecated.
It will be removed in 3.0.
# Upgrade to 2.6
## Added `Doctrine\ORM\EntityRepository::count()` method
`Doctrine\ORM\EntityRepository::count()` has been added. This new method has different
signature than `Countable::count()` (required parameter) and therefore are not compatible.
If your repository implemented the `Countable` interface, you will have to use
`$repository->count([])` instead and not implement `Countable` interface anymore.
## Minor BC BREAK: `Doctrine\ORM\Tools\Console\ConsoleRunner` is now final
Since it's just an utilitarian class and should not be inherited.
## Minor BC BREAK: removed `Doctrine\ORM\Query\QueryException::associationPathInverseSideNotSupported()`
Method `Doctrine\ORM\Query\QueryException::associationPathInverseSideNotSupported()`
now has a required parameter `$pathExpr`.
## Minor BC BREAK: removed `Doctrine\ORM\Query\Parser#isInternalFunction()`
Method `Doctrine\ORM\Query\Parser#isInternalFunction()` was removed because
the distinction between internal function and user defined DQL was removed.
[#6500](https://github.com/doctrine/orm/pull/6500)
## Minor BC BREAK: removed `Doctrine\ORM\ORMException#overwriteInternalDQLFunctionNotAllowed()`
Method `Doctrine\ORM\Query\Parser#overwriteInternalDQLFunctionNotAllowed()` was
removed because of the choice to allow users to overwrite internal functions, ie
`AVG`, `SUM`, `COUNT`, `MIN` and `MAX`. [#6500](https://github.com/doctrine/orm/pull/6500)
## PHP 7.1 is now required
Doctrine 2.6 now requires PHP 7.1 or newer.
As a consequence, automatic cache setup in Doctrine\ORM\Tools\Setup::create*Configuration() was changed:
- APCu extension (ext-apcu) will now be used instead of abandoned APC (ext-apc).
- Memcached extension (ext-memcached) will be used instead of obsolete Memcache (ext-memcache).
- XCache support was dropped as it doesn't work with PHP 7.
# Upgrade to 2.5
## Minor BC BREAK: removed `Doctrine\ORM\Query\SqlWalker#walkCaseExpression()`
Method `Doctrine\ORM\Query\SqlWalker#walkCaseExpression()` was unused and part
of the internal API of the ORM, so it was removed. [#5600](https://github.com/doctrine/orm/pull/5600).
## Minor BC BREAK: removed $className parameter on `AbstractEntityInheritancePersister#getSelectJoinColumnSQL()`
As `$className` parameter was not used in the method, it was safely removed.
## Minor BC BREAK: query cache key time is now a float
As of 2.5.5, the `QueryCacheEntry#time` property will contain a float value
instead of an integer in order to have more precision and also to be consistent
with the `TimestampCacheEntry#time`.
## Minor BC BREAK: discriminator map must now include all non-transient classes
It is now required that you declare the root of an inheritance in the
discriminator map.
When declaring an inheritance map, it was previously possible to skip the root
of the inheritance in the discriminator map. This was actually a validation
mistake by Doctrine2 and led to problems when trying to persist instances of
that class.
If you don't plan to persist instances some classes in your inheritance, then
either:
- make those classes `abstract`
- map those classes as `MappedSuperclass`
## Minor BC BREAK: ``EntityManagerInterface`` instead of ``EntityManager`` in type-hints
As of 2.5, classes requiring the ``EntityManager`` in any method signature will now require
an ``EntityManagerInterface`` instead.
If you are extending any of the following classes, then you need to check following
signatures:
- ``Doctrine\ORM\Tools\DebugUnitOfWorkListener#dumpIdentityMap(EntityManagerInterface $em)``
- ``Doctrine\ORM\Mapping\ClassMetadataFactory#setEntityManager(EntityManagerInterface $em)``
## Minor BC BREAK: Custom Hydrators API change
As of 2.5, `AbstractHydrator` does not enforce the usage of cache as part of
API, and now provides you a clean API for column information through the method
`hydrateColumnInfo($column)`.
Cache variable being passed around by reference is no longer needed since
Hydrators are per query instantiated since Doctrine 2.4.
## Minor BC BREAK: Entity based ``EntityManager#clear()`` calls follow cascade detach
Whenever ``EntityManager#clear()`` method gets called with a given entity class
name, until 2.4, it was only detaching the specific requested entity.
As of 2.5, ``EntityManager`` will follow configured cascades, providing a better
memory management since associations will be garbage collected, optimizing
resources consumption on long running jobs.
## BC BREAK: NamingStrategy interface changes
1. A new method ``embeddedFieldToColumnName($propertyName, $embeddedColumnName)``
This method generates the column name for fields of embedded objects. If you implement your custom NamingStrategy, you
now also need to implement this new method.
2. A change to method ``joinColumnName()`` to include the $className
## Updates on entities scheduled for deletion are no longer processed
In Doctrine 2.4, if you modified properties of an entity scheduled for deletion, UnitOfWork would
produce an UPDATE statement to be executed right before the DELETE statement. The entity in question
was therefore present in ``UnitOfWork#entityUpdates``, which means that ``preUpdate`` and ``postUpdate``
listeners were (quite pointlessly) called. In ``preFlush`` listeners, it used to be possible to undo
the scheduled deletion for updated entities (by calling ``persist()`` if the entity was found in both
``entityUpdates`` and ``entityDeletions``). This does not work any longer, because the entire changeset
calculation logic is optimized away.
## Minor BC BREAK: Default lock mode changed from LockMode::NONE to null in method signatures
A misconception concerning default lock mode values in method signatures lead to unexpected behaviour
in SQL statements on SQL Server. With a default lock mode of ``LockMode::NONE`` throughout the
method signatures in ORM, the table lock hint ``WITH (NOLOCK)`` was appended to all locking related
queries by default. This could result in unpredictable results because an explicit ``WITH (NOLOCK)``
table hint tells SQL Server to run a specific query in transaction isolation level READ UNCOMMITTED
instead of the default READ COMMITTED transaction isolation level.
Therefore there now is a distinction between ``LockMode::NONE`` and ``null`` to be able to tell
Doctrine whether to add table lock hints to queries by intention or not. To achieve this, the following
method signatures have been changed to declare ``$lockMode = null`` instead of ``$lockMode = LockMode::NONE``:
- ``Doctrine\ORM\Cache\Persister\AbstractEntityPersister#getSelectSQL()``
- ``Doctrine\ORM\Cache\Persister\AbstractEntityPersister#load()``
- ``Doctrine\ORM\Cache\Persister\AbstractEntityPersister#refresh()``
- ``Doctrine\ORM\Decorator\EntityManagerDecorator#find()``
- ``Doctrine\ORM\EntityManager#find()``
- ``Doctrine\ORM\EntityRepository#find()``
- ``Doctrine\ORM\Persisters\BasicEntityPersister#getSelectSQL()``
- ``Doctrine\ORM\Persisters\BasicEntityPersister#load()``
- ``Doctrine\ORM\Persisters\BasicEntityPersister#refresh()``
- ``Doctrine\ORM\Persisters\EntityPersister#getSelectSQL()``
- ``Doctrine\ORM\Persisters\EntityPersister#load()``
- ``Doctrine\ORM\Persisters\EntityPersister#refresh()``
- ``Doctrine\ORM\Persisters\JoinedSubclassPersister#getSelectSQL()``
You should update signatures for these methods if you have subclassed one of the above classes.
Please also check the calling code of these methods in your application and update if necessary.
**Note:**
This in fact is really a minor BC BREAK and should not have any affect on database vendors
other than SQL Server because it is the only one that supports and therefore cares about
``LockMode::NONE``. It's really just a FIX for SQL Server environments using ORM.
## Minor BC BREAK: `__clone` method not called anymore when entities are instantiated via metadata API
As of PHP 5.6, instantiation of new entities is deferred to the
[`doctrine/instantiator`](https://github.com/doctrine/instantiator) library, which will avoid calling `__clone`
or any public API on instantiated objects.
## BC BREAK: `Doctrine\ORM\Repository\DefaultRepositoryFactory` is now `final`
Please implement the `Doctrine\ORM\Repository\RepositoryFactory` interface instead of extending
the `Doctrine\ORM\Repository\DefaultRepositoryFactory`.
## BC BREAK: New object expression DQL queries now respects user provided aliasing and not return consumed fields
When executing DQL queries with new object expressions, instead of returning DTOs numerically indexes, it will now respect user provided aliases. Consider the following query:
SELECT new UserDTO(u.id,u.name) as user,new AddressDTO(a.street,a.postalCode) as address, a.id as addressId FROM User u INNER JOIN u.addresses a WITH a.isPrimary = true
Previously, your result would be similar to this:
array(
0=>array(
0=>{UserDTO object},
1=>{AddressDTO object},
2=>{u.id scalar},
3=>{u.name scalar},
4=>{a.street scalar},
5=>{a.postalCode scalar},
'addressId'=>{a.id scalar},
),
...
)
From now on, the resultset will look like this:
array(
0=>array(
'user'=>{UserDTO object},
'address'=>{AddressDTO object},
'addressId'=>{a.id scalar}
),
...
)
## Minor BC BREAK: added second parameter $indexBy in EntityRepository#createQueryBuilder method signature
Added way to access the underlying QueryBuilder#from() method's 'indexBy' parameter when using EntityRepository#createQueryBuilder()
# Upgrade to 2.4
## BC BREAK: Compatibility Bugfix in PersistentCollection#matching()
In Doctrine 2.3 it was possible to use the new ``matching($criteria)``
functionality by adding constraints for assocations based on ID:
Criteria::expr()->eq('association', $assocation->getId());
This functionality does not work on InMemory collections however, because
in memory criteria compares object values based on reference.
As of 2.4 the above code will throw an exception. You need to change
offending code to pass the ``$assocation`` reference directly:
Criteria::expr()->eq('association', $assocation);
## Composer is now the default autoloader
The test suite now runs with composer autoloading. Support for PEAR, and tarball autoloading is deprecated.
Support for GIT submodules is removed.
## OnFlush and PostFlush event always called
Before 2.4 the postFlush and onFlush events were only called when there were
actually entities that changed. Now these events are called no matter if there
are entities in the UoW or changes are found.
## Parenthesis are now considered in arithmetic expression
Before 2.4 parenthesis are not considered in arithmetic primary expression.
That's conceptually wrong, since it might result in wrong values. For example:
The DQL:
SELECT 100 / ( 2 * 2 ) FROM MyEntity
Before 2.4 it generates the SQL:
SELECT 100 / 2 * 2 FROM my_entity
Now parenthesis are considered, the previous DQL will generate:
SELECT 100 / (2 * 2) FROM my_entity
# Upgrade to 2.3
## Auto Discriminator Map breaks userland implementations with Listener
The new feature to detect discriminator maps automatically when none
are provided breaks userland implementations doing this with a
listener in ``loadClassMetadata`` event.
## EntityManager#find() not calls EntityRepository#find() anymore
Previous to 2.3, calling ``EntityManager#find()`` would be delegated to
``EntityRepository#find()``. This has lead to some unexpected behavior in the
core of Doctrine when people have overwritten the find method in their
repositories. That is why this behavior has been reversed in 2.3, and
``EntityRepository#find()`` calls ``EntityManager#find()`` instead.
## EntityGenerator add*() method generation
When generating an add*() method for a collection the EntityGenerator will now not
use the Type-Hint to get the singular for the collection name, but use the field-name
and strip a trailing "s" character if there is one.
## Merge copies non persisted properties too
When merging an entity in UoW not only mapped properties are copied, but also others.
## Query, QueryBuilder and NativeQuery parameters *BC break*
From now on, parameters in queries is an ArrayCollection instead of a simple array.
This affects heavily the usage of setParameters(), because it will not append anymore
parameters to query, but will actually override the already defined ones.
Whenever you are retrieving a parameter (ie. $query->getParameter(1)), you will
receive an instance of Query\Parameter, which contains the methods "getName",
"getValue" and "getType". Parameters are also only converted to when necessary, and
not when they are set.
Also, related functions were affected:
* execute($parameters, $hydrationMode) the argument $parameters can be either an key=>value array or an ArrayCollection instance
* iterate($parameters, $hydrationMode) the argument $parameters can be either an key=>value array or an ArrayCollection instance
* setParameters($parameters) the argument $parameters can be either an key=>value array or an ArrayCollection instance
* getParameters() now returns ArrayCollection instead of array
* getParameter($key) now returns Parameter instance instead of parameter value
## Query TreeWalker method renamed
Internal changes were made to DQL and SQL generation. If you have implemented your own TreeWalker,
you probably need to update it. The method walkJoinVariableDeclaration is now named walkJoin.
## New methods in TreeWalker interface *BC break*
Two methods getQueryComponents() and setQueryComponent() were added to the TreeWalker interface and all its implementations
including TreeWalkerAdapter, TreeWalkerChain and SqlWalker. If you have your own implementation not inheriting from one of the
above you must implement these new methods.
## Metadata Drivers
Metadata drivers have been rewritten to reuse code from `Doctrine\Persistence`. Anyone who is using the
`Doctrine\ORM\Mapping\Driver\Driver` interface should instead refer to
`Doctrine\Persistence\Mapping\Driver\MappingDriver`. Same applies to
`Doctrine\ORM\Mapping\Driver\AbstractFileDriver`: you should now refer to
`Doctrine\Persistence\Mapping\Driver\FileDriver`.
Also, following mapping drivers have been deprecated, please use their replacements in Doctrine\Common as listed:
* `Doctrine\ORM\Mapping\Driver\DriverChain` => `Doctrine\Persistence\Mapping\Driver\MappingDriverChain`
* `Doctrine\ORM\Mapping\Driver\PHPDriver` => `Doctrine\Persistence\Mapping\Driver\PHPDriver`
* `Doctrine\ORM\Mapping\Driver\StaticPHPDriver` => `Doctrine\Persistence\Mapping\Driver\StaticPHPDriver`
# Upgrade to 2.2
## ResultCache implementation rewritten
The result cache is completely rewritten and now works on the database result level, not inside the ORM AbstractQuery
anymore. This means that for result cached queries the hydration will now always be performed again, regardless of
the hydration mode. Affected areas are:
1. Fixes the problem that entities coming from the result cache were not registered in the UnitOfWork
leading to problems during EntityManager#flush. Calls to EntityManager#merge are not necessary anymore.
2. Affects the array hydrator which now includes the overhead of hydration compared to caching the final result.
The API is backwards compatible however most of the getter methods on the `AbstractQuery` object are now
deprecated in favor of calling AbstractQuery#getQueryCacheProfile(). This method returns a `Doctrine\DBAL\Cache\QueryCacheProfile`
instance with access to result cache driver, lifetime and cache key.
## EntityManager#getPartialReference() creates read-only entity
Entities returned from EntityManager#getPartialReference() are now marked as read-only if they
haven't been in the identity map before. This means objects of this kind never lead to changes
in the UnitOfWork.
## Fields omitted in a partial DQL query or a native query are never updated
Fields of an entity that are not returned from a partial DQL Query or native SQL query
will never be updated through an UPDATE statement.
## Removed support for onUpdate in @JoinColumn
The onUpdate foreign key handling makes absolutely no sense in an ORM. Additionally Oracle doesn't even support it. Support for it is removed.
## Changes in Annotation Handling
There have been some changes to the annotation handling in Common 2.2 again, that affect how people with old configurations
from 2.0 have to configure the annotation driver if they don't use `Configuration::newDefaultAnnotationDriver()`:
// Register the ORM Annotations in the AnnotationRegistry
AnnotationRegistry::registerFile('path/to/Doctrine/ORM/Mapping/Driver/DoctrineAnnotations.php');
$reader = new \Doctrine\Common\Annotations\SimpleAnnotationReader();
$reader->addNamespace('Doctrine\ORM\Mapping');
$reader = new \Doctrine\Common\Annotations\CachedReader($reader, new ArrayCache());
$driver = new AnnotationDriver($reader, (array)$paths);
$config->setMetadataDriverImpl($driver);
## Scalar mappings can now be omitted from DQL result
You are now allowed to mark scalar SELECT expressions as HIDDEN an they are not hydrated anymore.
Example:
SELECT u, SUM(a.id) AS HIDDEN numArticles FROM User u LEFT JOIN u.Articles a ORDER BY numArticles DESC HAVING numArticles > 10
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
## Map entities as scalars in DQL result
When hydrating to array or even a mixed result in object hydrator, previously you had the 0 index holding you entity instance.
You are now allowed to alias this, providing more flexibility for you code.
Example:
SELECT u AS user FROM User u
Will now return a collection of arrays with index "user" pointing to the User object instance.
## Performance optimizations
Thousands of lines were completely reviewed and optimized for best performance.
Removed redundancy and improved code readability made now internal Doctrine code easier to understand.
Also, Doctrine 2.2 now is around 10-15% faster than 2.1.
## EntityManager#find(null)
Previously EntityManager#find(null) returned null. It now throws an exception.
# Upgrade to 2.1
## Interface for EntityRepository
The EntityRepository now has an interface Doctrine\Persistence\ObjectRepository. This means that your classes that override EntityRepository and extend find(), findOneBy() or findBy() must be adjusted to follow this interface.
## AnnotationReader changes
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:
// new call to the AnnotationRegistry
\Doctrine\Common\Annotations\AnnotationRegistry::registerFile('/doctrine-src/src/Mapping/Driver/DoctrineAnnotations.php');
$reader = new \Doctrine\Common\Annotations\AnnotationReader();
$reader->setDefaultAnnotationNamespace('Doctrine\ORM\Mapping\\');
// new code necessary starting here
$reader->setIgnoreNotImportedAnnotations(true);
$reader->setEnableParsePhpImports(false);
$reader = new \Doctrine\Common\Annotations\CachedReader(
new \Doctrine\Common\Annotations\IndexedReader($reader), new ArrayCache()
);
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.
# Update from 2.0-BETA3 to 2.0-BETA4
## XML Driver <change-tracking-policy /> element demoted to attribute
We changed how the XML Driver allows to define the change-tracking-policy. The working case is now:
<entity change-tracking-policy="DEFERRED_IMPLICT" />
# Update from 2.0-BETA2 to 2.0-BETA3
## Serialization of Uninitialized Proxies
As of Beta3 you can now serialize uninitialized proxies, an exception will only be thrown when
trying to access methods on the unserialized proxy as long as it has not been re-attached to the
EntityManager using `EntityManager#merge()`. See this example:
$proxy = $em->getReference('User', 1);
$serializedProxy = serialize($proxy);
$detachedProxy = unserialized($serializedProxy);
echo $em->contains($detachedProxy); // FALSE
try {
$detachedProxy->getId(); // uninitialized detached proxy
} catch(Exception $e) {
}
$attachedProxy = $em->merge($detachedProxy);
echo $attackedProxy->getId(); // works!
## Changed SQL implementation of Postgres and Oracle DateTime types
The DBAL Type "datetime" included the Timezone Offset in both Postgres and Oracle. As of this version they are now
generated without Timezone (TIMESTAMP WITHOUT TIME ZONE instead of TIMESTAMP WITH TIME ZONE).
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)
for more details as well as migration issues for PostgreSQL and Oracle.
Both Postgres and Oracle will throw Exceptions during hydration of Objects with "DateTime" fields unless migration steps are taken!
## Removed multi-dot/deep-path expressions in DQL
The support for implicit joins in DQL through the multi-dot/Deep Path Expressions
was dropped. For example:
SELECT u FROM User u WHERE u.group.name = ?1
See the "u.group.id" here is using multi dots (deep expression) to walk
through the graph of objects and properties. Internally the DQL parser
would rewrite these queries to:
SELECT u FROM User u JOIN u.group g WHERE g.name = ?1
This explicit notation will be the only supported notation as of now. The internal
handling of multi-dots in the DQL Parser was very complex, error prone in edge cases
and required special treatment for several features we added. Additionally
it had edge cases that could not be solved without making the DQL Parser
even much more complex. For this reason we will drop the support for the
deep path expressions to increase maintainability and overall performance
of the DQL parsing process. This will benefit any DQL query being parsed,
even those not using deep path expressions.
Note that the generated SQL of both notations is exactly the same! You
don't loose anything through this.
## Default Allocation Size for Sequences
The default allocation size for sequences has been changed from 10 to 1. This step was made
to not cause confusion with users and also because it is partly some kind of premature optimization.
# Update from 2.0-BETA1 to 2.0-BETA2
There are no backwards incompatible changes in this release.
# Upgrade from 2.0-ALPHA4 to 2.0-BETA1
## EntityRepository deprecates access to protected variables
Instead of accessing protected variables for the EntityManager in
a custom EntityRepository it is now required to use the getter methods
for all the three instance variables:
* `$this->_em` now accessible through `$this->getEntityManager()`
* `$this->_class` now accessible through `$this->getClassMetadata()`
* `$this->_entityName` now accessible through `$this->getEntityName()`
Important: For Beta 2 the protected visibility of these three properties will be
changed to private!
## Console migrated to Symfony Console
The Doctrine CLI has been replaced by Symfony Console Configuration
Instead of having to specify:
[php]
$cliConfig = new CliConfiguration();
$cliConfig->setAttribute('em', $entityManager);
You now have to configure the script like:
[php]
$helperSet = new \Symfony\Components\Console\Helper\HelperSet(array(
'db' => new \Doctrine\DBAL\Tools\Console\Helper\ConnectionHelper($em->getConnection()),
'em' => new \Doctrine\ORM\Tools\Console\Helper\EntityManagerHelper($em)
));
## Console: No need for Mapping Paths anymore
In previous versions you had to specify the --from and --from-path options
to show where your mapping paths are from the console. However this information
is already known from the Mapping Driver configuration, so the requirement
for this options were dropped.
Instead for each console command all the entities are loaded and to
restrict the operation to one or more sub-groups you can use the --filter flag.
## AnnotationDriver is not a default mapping driver anymore
In conjunction with the recent changes to Console we realized that the
annotations driver being a default metadata driver lead to lots of glue
code in the console components to detect where entities lie and how to load
them for batch updates like SchemaTool and other commands. However the
annotations driver being a default driver does not really help that much
anyways.
Therefore we decided to break backwards compatibility in this issue and drop
the support for Annotations as Default Driver and require our users to
specify the driver explicitly (which allows us to ask for the path to all
entities).
If you are using the annotations metadata driver as default driver, you
have to add the following lines to your bootstrap code:
$driverImpl = $config->newDefaultAnnotationDriver(array(__DIR__."/Entities"));
$config->setMetadataDriverImpl($driverImpl);
You have to specify the path to your entities as either string of a single
path or array of multiple paths
to your entities. This information will be used by all console commands to
access all entities.
Xml and Yaml Drivers work as before!
## New inversedBy attribute
It is now *mandatory* that the owning side of a bidirectional association specifies the
'inversedBy' attribute that points to the name of the field on the inverse side that completes
the association. Example:
[php]
// BEFORE (ALPHA4 AND EARLIER)
class User
{
//...
/** @OneToOne(targetEntity="Address", mappedBy="user") */
private $address;
//...
}
class Address
{
//...
/** @OneToOne(targetEntity="User") */
private $user;
//...
}
// SINCE BETA1
// User class DOES NOT CHANGE
class Address
{
//...
/** @OneToOne(targetEntity="User", inversedBy="address") */
private $user;
//...
}
Thus, the inversedBy attribute is the counterpart to the mappedBy attribute. This change
was necessary to enable some simplifications and further performance improvements. We
apologize for the inconvenience.
## Default Property for Field Mappings
The "default" option for database column defaults has been removed. If desired, database column defaults can
be implemented by using the columnDefinition attribute of the @Column annotation (or the appropriate XML and YAML equivalents).
Prefer PHP default values, if possible.
## Selecting Partial Objects
Querying for partial objects now has a new syntax. The old syntax to query for partial objects
now has a different meaning. This is best illustrated by an example. If you previously
had a DQL query like this:
[sql]
SELECT u.id, u.name FROM User u
Since BETA1, simple state field path expressions in the select clause are used to select
object fields as plain scalar values (something that was not possible before).
To achieve the same result as previously (that is, a partial object with only id and name populated)
you need to use the following, explicit syntax:
[sql]
SELECT PARTIAL u.{id,name} FROM User u
## XML Mapping Driver
The 'inheritance-type' attribute changed to take last bit of ClassMetadata constant names, i.e.
NONE, SINGLE_TABLE, INHERITANCE_TYPE_JOINED
## YAML Mapping Driver
The way to specify lifecycle callbacks in YAML Mapping driver was changed to allow for multiple callbacks
per event. The Old syntax ways:
[yaml]
lifecycleCallbacks:
doStuffOnPrePersist: prePersist
doStuffOnPostPersist: postPersist
The new syntax is:
[yaml]
lifecycleCallbacks:
prePersist: [ doStuffOnPrePersist, doOtherStuffOnPrePersistToo ]
postPersist: [ doStuffOnPostPersist ]
## PreUpdate Event Listeners
Event Listeners listening to the 'preUpdate' event can only affect the primitive values of entity changesets
by using the API on the `PreUpdateEventArgs` instance passed to the preUpdate listener method. Any changes
to the state of the entitys properties won't affect the database UPDATE statement anymore. This gives drastic
performance benefits for the preUpdate event.
## Collection API
The Collection interface in the Common package has been updated with some missing methods
that were present only on the default implementation, ArrayCollection. Custom collection
implementations need to be updated to adhere to the updated interface.
# Upgrade from 2.0-ALPHA3 to 2.0-ALPHA4
## CLI Controller changes
CLI main object changed its name and namespace. Renamed from Doctrine\ORM\Tools\Cli to Doctrine\Common\Cli\CliController.
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:
[php]
$cli->getNamespace('Core')->addTask('my-example', '\MyProject\Tools\Cli\Tasks\MyExampleTask');
## CLI Tasks documentation
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.
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.
## Changes in Method Signatures
* A bunch of Methods on both Doctrine\DBAL\Platforms\AbstractPlatform and Doctrine\DBAL\Schema\AbstractSchemaManager
have changed quite significantly by adopting the new Schema instance objects.
## Renamed Methods
* Doctrine\ORM\AbstractQuery::setExpireResultCache() -> expireResultCache()
* Doctrine\ORM\Query::setExpireQueryCache() -> expireQueryCache()
## SchemaTool Changes
* "doctrine schema-tool --drop" now always drops the complete database instead of
only those tables defined by the current database model. The previous method had
problems when foreign keys of orphaned tables pointed to tables that were scheduled
for deletion.
* Use "doctrine schema-tool --update" to get a save incremental update for your
database schema without deleting any unused tables, sequences or foreign keys.
* Use "doctrine schema-tool --complete-update" to do a full incremental update of
your schema.
# Upgrade from 2.0-ALPHA2 to 2.0-ALPHA3
This section details the changes made to Doctrine 2.0-ALPHA3 to make it easier for you
to upgrade your projects to use this version.
## CLI Changes
The $args variable used in the cli-config.php for configuring the Doctrine CLI has been renamed to $globalArguments.
## Proxy class changes
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:
[php]
// step 1: configure directory for proxy classes
// $config instanceof Doctrine\ORM\Configuration
$config->setProxyDir('/path/to/myproject/lib/MyProject/Generated/Proxies');
$config->setProxyNamespace('MyProject\Generated\Proxies');
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.
Generating the proxy classes into a namespace within your class library is the recommended setup.
Entities with initialized proxy objects can now be serialized and unserialized properly from within the same application.
For more details refer to the Configuration section of the manual.
## Removed allowPartialObjects configuration option
The allowPartialObjects configuration option together with the `Configuration#getAllowPartialObjects` and `Configuration#setAllowPartialObjects` methods have been removed.
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.
## Renamed Methods
* Doctrine\ORM\Configuration#getCacheDir() to getProxyDir()
* Doctrine\ORM\Configuration#setCacheDir($dir) to setProxyDir($dir)
|