1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
namespace Doctrine\Tests\ORM\Functional; |
4
|
|
|
|
5
|
|
|
use Doctrine\DBAL\DriverManager; |
6
|
|
|
use Doctrine\DBAL\Logging\DebugStack; |
7
|
|
|
use Doctrine\DBAL\Logging\SQLLogger; |
8
|
|
|
use Doctrine\ORM\Configuration; |
9
|
|
|
use Doctrine\ORM\EntityManager; |
10
|
|
|
use Doctrine\ORM\Proxy\Proxy; |
11
|
|
|
use Doctrine\ORM\Tools\SchemaTool; |
12
|
|
|
use Doctrine\Tests\Models\Generic\DateTimeModel; |
13
|
|
|
use Doctrine\Tests\OrmFunctionalTestCase; |
14
|
|
|
use Doctrine\Tests\VerifyDeprecations; |
15
|
|
|
|
16
|
|
|
class MergeProxiesTest extends OrmFunctionalTestCase |
17
|
|
|
{ |
18
|
|
|
use VerifyDeprecations; |
19
|
|
|
|
20
|
|
|
/** |
21
|
|
|
* {@inheritDoc} |
22
|
|
|
*/ |
23
|
|
|
protected function setUp() |
24
|
|
|
{ |
25
|
|
|
$this->useModelSet('generic'); |
26
|
|
|
|
27
|
|
|
parent::setUp(); |
28
|
|
|
} |
29
|
|
|
|
30
|
|
|
/** @after */ |
31
|
|
|
public function ensureTestGeneratedDeprecationMessages() : void |
32
|
|
|
{ |
33
|
|
|
$this->assertHasDeprecationMessages(); |
34
|
|
|
} |
35
|
|
|
|
36
|
|
|
/** |
37
|
|
|
* @group DDC-1392 |
38
|
|
|
* @group DDC-1734 |
39
|
|
|
* @group DDC-3368 |
40
|
|
|
* @group #1172 |
41
|
|
|
*/ |
42
|
|
|
public function testMergeDetachedUnInitializedProxy() |
43
|
|
|
{ |
44
|
|
|
$detachedUninitialized = $this->_em->getReference(DateTimeModel::class, 123); |
45
|
|
|
|
46
|
|
|
$this->_em->clear(); |
47
|
|
|
|
48
|
|
|
$managed = $this->_em->getReference(DateTimeModel::class, 123); |
49
|
|
|
|
50
|
|
|
$this->assertSame($managed, $this->_em->merge($detachedUninitialized)); |
|
|
|
|
51
|
|
|
|
52
|
|
|
$this->assertFalse($managed->__isInitialized()); |
53
|
|
|
$this->assertFalse($detachedUninitialized->__isInitialized()); |
54
|
|
|
} |
55
|
|
|
|
56
|
|
|
/** |
57
|
|
|
* @group DDC-1392 |
58
|
|
|
* @group DDC-1734 |
59
|
|
|
* @group DDC-3368 |
60
|
|
|
* @group #1172 |
61
|
|
|
*/ |
62
|
|
|
public function testMergeUnserializedUnInitializedProxy() |
63
|
|
|
{ |
64
|
|
|
$detachedUninitialized = $this->_em->getReference(DateTimeModel::class, 123); |
65
|
|
|
|
66
|
|
|
$this->_em->clear(); |
67
|
|
|
|
68
|
|
|
$managed = $this->_em->getReference(DateTimeModel::class, 123); |
69
|
|
|
|
70
|
|
|
$this->assertSame( |
71
|
|
|
$managed, |
72
|
|
|
$this->_em->merge(unserialize(serialize($this->_em->merge($detachedUninitialized)))) |
|
|
|
|
73
|
|
|
); |
74
|
|
|
|
75
|
|
|
$this->assertFalse($managed->__isInitialized()); |
76
|
|
|
$this->assertFalse($detachedUninitialized->__isInitialized()); |
77
|
|
|
} |
78
|
|
|
|
79
|
|
|
/** |
80
|
|
|
* @group DDC-1392 |
81
|
|
|
* @group DDC-1734 |
82
|
|
|
* @group DDC-3368 |
83
|
|
|
* @group #1172 |
84
|
|
|
*/ |
85
|
|
|
public function testMergeManagedProxy() |
86
|
|
|
{ |
87
|
|
|
$managed = $this->_em->getReference(DateTimeModel::class, 123); |
88
|
|
|
|
89
|
|
|
$this->assertSame($managed, $this->_em->merge($managed)); |
|
|
|
|
90
|
|
|
|
91
|
|
|
$this->assertFalse($managed->__isInitialized()); |
92
|
|
|
} |
93
|
|
|
|
94
|
|
|
/** |
95
|
|
|
* @group DDC-1392 |
96
|
|
|
* @group DDC-1734 |
97
|
|
|
* @group DDC-3368 |
98
|
|
|
* @group #1172 |
99
|
|
|
* |
100
|
|
|
* Bug discovered while working on DDC-2704 - merging towards un-initialized proxies does not initialize them, |
101
|
|
|
* causing merged data to be lost when they are actually initialized |
102
|
|
|
*/ |
103
|
|
|
public function testMergeWithExistingUninitializedManagedProxy() |
104
|
|
|
{ |
105
|
|
|
$date = new DateTimeModel(); |
106
|
|
|
|
107
|
|
|
$this->_em->persist($date); |
108
|
|
|
$this->_em->flush($date); |
109
|
|
|
$this->_em->clear(); |
110
|
|
|
|
111
|
|
|
$managed = $this->_em->getReference(DateTimeModel::class, $date->id); |
112
|
|
|
|
113
|
|
|
$this->assertInstanceOf(Proxy::class, $managed); |
114
|
|
|
$this->assertFalse($managed->__isInitialized()); |
115
|
|
|
|
116
|
|
|
$date->date = $dateTime = new \DateTime(); |
117
|
|
|
|
118
|
|
|
$this->assertSame($managed, $this->_em->merge($date)); |
|
|
|
|
119
|
|
|
$this->assertTrue($managed->__isInitialized()); |
120
|
|
|
$this->assertSame($dateTime, $managed->date, 'Data was merged into the proxy after initialization'); |
121
|
|
|
} |
122
|
|
|
|
123
|
|
|
/** |
124
|
|
|
* @group DDC-1392 |
125
|
|
|
* @group DDC-1734 |
126
|
|
|
* @group DDC-3368 |
127
|
|
|
* @group #1172 |
128
|
|
|
*/ |
129
|
|
|
public function testMergingProxyFromDifferentEntityManagerWithExistingManagedInstanceDoesNotReplaceInitializer() |
130
|
|
|
{ |
131
|
|
|
$em1 = $this->createEntityManager($logger1 = new DebugStack()); |
132
|
|
|
$em2 = $this->createEntityManager($logger2 = new DebugStack()); |
133
|
|
|
|
134
|
|
|
$file1 = new DateTimeModel(); |
135
|
|
|
$file2 = new DateTimeModel(); |
136
|
|
|
|
137
|
|
|
$em1->persist($file1); |
138
|
|
|
$em2->persist($file2); |
139
|
|
|
$em1->flush(); |
140
|
|
|
$em2->flush(); |
141
|
|
|
$em1->clear(); |
142
|
|
|
$em2->clear(); |
143
|
|
|
|
144
|
|
|
$queryCount1 = count($logger1->queries); |
145
|
|
|
$queryCount2 = count($logger2->queries); |
146
|
|
|
|
147
|
|
|
$proxy1 = $em1->getReference(DateTimeModel::class, $file1->id); |
148
|
|
|
$proxy2 = $em2->getReference(DateTimeModel::class, $file1->id); |
149
|
|
|
$merged2 = $em2->merge($proxy1); |
|
|
|
|
150
|
|
|
|
151
|
|
|
$this->assertNotSame($proxy1, $merged2); |
152
|
|
|
$this->assertSame($proxy2, $merged2); |
153
|
|
|
|
154
|
|
|
$this->assertFalse($proxy1->__isInitialized()); |
155
|
|
|
$this->assertFalse($proxy2->__isInitialized()); |
156
|
|
|
|
157
|
|
|
$proxy1->__load(); |
158
|
|
|
|
159
|
|
|
$this->assertCount( |
160
|
|
|
$queryCount1 + 1, |
161
|
|
|
$logger1->queries, |
162
|
|
|
'Loading the first proxy was done through the first entity manager' |
163
|
|
|
); |
164
|
|
|
$this->assertCount( |
165
|
|
|
$queryCount2, |
166
|
|
|
$logger2->queries, |
167
|
|
|
'No queries were executed on the second entity manager, as it is unrelated with the first proxy' |
168
|
|
|
); |
169
|
|
|
|
170
|
|
|
$proxy2->__load(); |
171
|
|
|
|
172
|
|
|
$this->assertCount( |
173
|
|
|
$queryCount1 + 1, |
174
|
|
|
$logger1->queries, |
175
|
|
|
'Loading the second proxy does not affect the first entity manager' |
176
|
|
|
); |
177
|
|
|
$this->assertCount( |
178
|
|
|
$queryCount2 + 1, |
179
|
|
|
$logger2->queries, |
180
|
|
|
'Loading of the second proxy instance was done through the second entity manager' |
181
|
|
|
); |
182
|
|
|
} |
183
|
|
|
|
184
|
|
|
/** |
185
|
|
|
* @group DDC-1392 |
186
|
|
|
* @group DDC-1734 |
187
|
|
|
* @group DDC-3368 |
188
|
|
|
* @group #1172 |
189
|
|
|
*/ |
190
|
|
|
public function testMergingUnInitializedProxyDoesNotInitializeIt() |
191
|
|
|
{ |
192
|
|
|
$em1 = $this->createEntityManager($logger1 = new DebugStack()); |
193
|
|
|
$em2 = $this->createEntityManager($logger2 = new DebugStack()); |
194
|
|
|
|
195
|
|
|
$file1 = new DateTimeModel(); |
196
|
|
|
$file2 = new DateTimeModel(); |
197
|
|
|
|
198
|
|
|
$em1->persist($file1); |
199
|
|
|
$em2->persist($file2); |
200
|
|
|
$em1->flush(); |
201
|
|
|
$em2->flush(); |
202
|
|
|
$em1->clear(); |
203
|
|
|
$em2->clear(); |
204
|
|
|
|
205
|
|
|
$queryCount1 = count($logger1->queries); |
206
|
|
|
$queryCount2 = count($logger1->queries); |
207
|
|
|
|
208
|
|
|
$unManagedProxy = $em1->getReference(DateTimeModel::class, $file1->id); |
209
|
|
|
$mergedInstance = $em2->merge($unManagedProxy); |
|
|
|
|
210
|
|
|
|
211
|
|
|
$this->assertNotInstanceOf(Proxy::class, $mergedInstance); |
212
|
|
|
$this->assertNotSame($unManagedProxy, $mergedInstance); |
213
|
|
|
$this->assertFalse($unManagedProxy->__isInitialized()); |
214
|
|
|
|
215
|
|
|
$this->assertCount( |
216
|
|
|
$queryCount1, |
217
|
|
|
$logger1->queries, |
218
|
|
|
'Loading the merged instance affected only the first entity manager' |
219
|
|
|
); |
220
|
|
|
$this->assertCount( |
221
|
|
|
$queryCount1 + 1, |
222
|
|
|
$logger2->queries, |
223
|
|
|
'Loading the merged instance was done via the second entity manager' |
224
|
|
|
); |
225
|
|
|
|
226
|
|
|
$unManagedProxy->__load(); |
227
|
|
|
|
228
|
|
|
$this->assertCount( |
229
|
|
|
$queryCount1 + 1, |
230
|
|
|
$logger1->queries, |
231
|
|
|
'Loading the first proxy was done through the first entity manager' |
232
|
|
|
); |
233
|
|
|
$this->assertCount( |
234
|
|
|
$queryCount2 + 1, |
235
|
|
|
$logger2->queries, |
236
|
|
|
'No queries were executed on the second entity manager, as it is unrelated with the first proxy' |
237
|
|
|
); |
238
|
|
|
} |
239
|
|
|
|
240
|
|
|
/** |
241
|
|
|
* @param SQLLogger $logger |
242
|
|
|
* |
243
|
|
|
* @return EntityManager |
244
|
|
|
*/ |
245
|
|
|
private function createEntityManager(SQLLogger $logger) |
246
|
|
|
{ |
247
|
|
|
$config = new Configuration(); |
248
|
|
|
|
249
|
|
|
$config->setProxyDir(realpath(__DIR__ . '/../../Proxies')); |
250
|
|
|
$config->setProxyNamespace('Doctrine\Tests\Proxies'); |
251
|
|
|
$config->setMetadataDriverImpl($config->newDefaultAnnotationDriver( |
252
|
|
|
[realpath(__DIR__ . '/../../Models/Cache')], |
253
|
|
|
true |
254
|
|
|
)); |
255
|
|
|
$config->setSQLLogger($logger); |
256
|
|
|
|
257
|
|
|
// always runs on sqlite to prevent multi-connection race-conditions with the test suite |
258
|
|
|
// multi-connection is not relevant for the purpose of checking locking here, but merely |
259
|
|
|
// to stub out DB-level access and intercept it |
260
|
|
|
$connection = DriverManager::getConnection( |
261
|
|
|
[ |
262
|
|
|
'driver' => 'pdo_sqlite', |
263
|
|
|
'memory' => true |
264
|
|
|
], |
265
|
|
|
$config |
266
|
|
|
); |
267
|
|
|
|
268
|
|
|
|
269
|
|
|
$entityManager = EntityManager::create($connection, $config); |
270
|
|
|
|
271
|
|
|
(new SchemaTool($entityManager))->createSchema([$entityManager->getClassMetadata(DateTimeModel::class)]); |
272
|
|
|
|
273
|
|
|
return $entityManager; |
274
|
|
|
} |
275
|
|
|
} |
276
|
|
|
|
This function has been deprecated. The supplier of the function has supplied an explanatory message.
The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.