Completed
Pull Request — master (#6479)
by Luís
11:06
created

testFlushManyExplicitEntities()   B

Complexity

Conditions 1
Paths 1

Size

Total Lines 30
Code Lines 21

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 30
c 0
b 0
f 0
rs 8.8571
cc 1
eloc 21
nc 1
nop 0
1
<?php
2
3
namespace Doctrine\Tests\ORM\Functional;
4
5
use Doctrine\DBAL\Logging\DebugStack;
6
use Doctrine\ORM\EntityNotFoundException;
7
use Doctrine\ORM\Mapping\ClassMetadata;
8
use Doctrine\ORM\ORMInvalidArgumentException;
9
use Doctrine\ORM\PersistentCollection;
10
use Doctrine\ORM\Proxy\Proxy;
11
use Doctrine\ORM\Query;
12
use Doctrine\ORM\UnitOfWork;
13
use Doctrine\Tests\Models\CMS\CmsAddress;
14
use Doctrine\Tests\Models\CMS\CmsArticle;
15
use Doctrine\Tests\Models\CMS\CmsComment;
16
use Doctrine\Tests\Models\CMS\CmsPhonenumber;
17
use Doctrine\Tests\Models\CMS\CmsUser;
18
use Doctrine\Tests\OrmFunctionalTestCase;
19
20
class BasicFunctionalTest extends OrmFunctionalTestCase
21
{
22
    protected function setUp()
23
    {
24
        $this->useModelSet('cms');
25
        parent::setUp();
26
    }
27
28
    public function testBasicUnitsOfWorkWithOneToManyAssociation()
29
    {
30
        // Create
31
        $user = new CmsUser;
32
        $user->name = 'Roman';
33
        $user->username = 'romanb';
34
        $user->status = 'developer';
35
        $this->_em->persist($user);
36
37
        $this->_em->flush();
38
39
        $this->assertTrue(is_numeric($user->id));
40
        $this->assertTrue($this->_em->contains($user));
41
42
        // Read
43
        $user2 = $this->_em->find(CmsUser::class, $user->id);
44
        $this->assertTrue($user === $user2);
45
46
        // Add a phonenumber
47
        $ph = new CmsPhonenumber;
48
        $ph->phonenumber = "12345";
49
        $user->addPhonenumber($ph);
50
        $this->_em->flush();
51
        $this->assertTrue($this->_em->contains($ph));
52
        $this->assertTrue($this->_em->contains($user));
53
54
        // Update name
55
        $user->name = 'guilherme';
56
        $this->_em->flush();
57
        $this->assertEquals('guilherme', $user->name);
58
59
        // Add another phonenumber
60
        $ph2 = new CmsPhonenumber;
61
        $ph2->phonenumber = "6789";
62
        $user->addPhonenumber($ph2);
63
        $this->_em->flush();
64
        $this->assertTrue($this->_em->contains($ph2));
65
66
        // Delete
67
        $this->_em->remove($user);
68
        $this->assertTrue($this->_em->getUnitOfWork()->isScheduledForDelete($user));
69
        $this->assertTrue($this->_em->getUnitOfWork()->isScheduledForDelete($ph));
70
        $this->assertTrue($this->_em->getUnitOfWork()->isScheduledForDelete($ph2));
71
        $this->_em->flush();
72
        $this->assertFalse($this->_em->getUnitOfWork()->isScheduledForDelete($user));
73
        $this->assertFalse($this->_em->getUnitOfWork()->isScheduledForDelete($ph));
74
        $this->assertFalse($this->_em->getUnitOfWork()->isScheduledForDelete($ph2));
75
        $this->assertEquals(UnitOfWork::STATE_NEW, $this->_em->getUnitOfWork()->getEntityState($user));
76
        $this->assertEquals(UnitOfWork::STATE_NEW, $this->_em->getUnitOfWork()->getEntityState($ph));
77
        $this->assertEquals(UnitOfWork::STATE_NEW, $this->_em->getUnitOfWork()->getEntityState($ph2));
78
    }
79
80
    public function testOneToManyAssociationModification()
81
    {
82
        $user = new CmsUser;
83
        $user->name = 'Roman';
84
        $user->username = 'romanb';
85
        $user->status = 'developer';
86
87
        $ph1 = new CmsPhonenumber;
88
        $ph1->phonenumber = "0301234";
89
        $ph2 = new CmsPhonenumber;
90
        $ph2->phonenumber = "987654321";
91
92
        $user->addPhonenumber($ph1);
93
        $user->addPhonenumber($ph2);
94
95
        $this->_em->persist($user);
96
        $this->_em->flush();
97
98
        // Remove the first element from the collection
99
        unset($user->phonenumbers[0]);
100
        $ph1->user = null; // owning side!
101
102
        $this->_em->flush();
103
104
        $this->assertEquals(1, count($user->phonenumbers));
105
        $this->assertNull($ph1->user);
106
    }
107
108
    public function testBasicOneToOne()
109
    {
110
        //$this->_em->getConnection()->getConfiguration()->setSQLLogger(new \Doctrine\DBAL\Logging\EchoSQLLogger);
111
        $user = new CmsUser;
112
        $user->name = 'Roman';
113
        $user->username = 'romanb';
114
        $user->status = 'developer';
115
116
        $address = new CmsAddress;
117
        $address->country = 'Germany';
118
        $address->city = 'Berlin';
119
        $address->zip = '12345';
120
121
        $user->address = $address; // inverse side
122
        $address->user = $user; // owning side!
123
124
        $this->_em->persist($user);
125
        $this->_em->flush();
126
127
        // Check that the foreign key has been set
128
        $userId = $this->_em->getConnection()->executeQuery(
129
            "SELECT user_id FROM cms_addresses WHERE id=?", [$address->id]
130
        )->fetchColumn();
131
        $this->assertTrue(is_numeric($userId));
132
133
        $this->_em->clear();
134
135
        $user2 = $this->_em->createQuery('select u from \Doctrine\Tests\Models\CMS\CmsUser u where u.id=?1')
136
                ->setParameter(1, $userId)
137
                ->getSingleResult();
138
139
        // Address has been eager-loaded because it cant be lazy
140
        $this->assertInstanceOf(CmsAddress::class, $user2->address);
141
        $this->assertNotInstanceOf(Proxy::class, $user2->address);
142
    }
143
144
    /**
145
     * @group DDC-1230
146
     */
147
    public function testRemove()
148
    {
149
        $user = new CmsUser;
150
        $user->name = 'Guilherme';
151
        $user->username = 'gblanco';
152
        $user->status = 'developer';
153
154
        $this->assertEquals(UnitOfWork::STATE_NEW, $this->_em->getUnitOfWork()->getEntityState($user), "State should be UnitOfWork::STATE_NEW");
155
156
        $this->_em->persist($user);
157
158
        $this->assertEquals(UnitOfWork::STATE_MANAGED, $this->_em->getUnitOfWork()->getEntityState($user), "State should be UnitOfWork::STATE_MANAGED");
159
160
        $this->_em->remove($user);
161
162
        $this->assertEquals(UnitOfWork::STATE_NEW, $this->_em->getUnitOfWork()->getEntityState($user), "State should be UnitOfWork::STATE_NEW");
163
164
        $this->_em->persist($user);
165
        $this->_em->flush();
166
        $id = $user->getId();
167
168
        $this->_em->remove($user);
169
170
        $this->assertEquals(UnitOfWork::STATE_REMOVED, $this->_em->getUnitOfWork()->getEntityState($user), "State should be UnitOfWork::STATE_REMOVED");
171
        $this->_em->flush();
172
173
        $this->assertEquals(UnitOfWork::STATE_NEW, $this->_em->getUnitOfWork()->getEntityState($user), "State should be UnitOfWork::STATE_NEW");
174
175
        $this->assertNull($this->_em->find(CmsUser::class, $id));
176
    }
177
178
    public function testOneToManyOrphanRemoval()
179
    {
180
        $user = new CmsUser;
181
        $user->name = 'Guilherme';
182
        $user->username = 'gblanco';
183
        $user->status = 'developer';
184
185
        for ($i=0; $i<3; ++$i) {
186
            $phone = new CmsPhonenumber;
187
            $phone->phonenumber = 100 + $i;
188
            $user->addPhonenumber($phone);
189
        }
190
191
        $this->_em->persist($user);
192
193
        $this->_em->flush();
194
195
        $user->getPhonenumbers()->remove(0);
196
        $this->assertEquals(2, count($user->getPhonenumbers()));
197
198
        $this->_em->flush();
199
200
        // Check that there are just 2 phonenumbers left
201
        $count = $this->_em->getConnection()->fetchColumn("SELECT COUNT(*) FROM cms_phonenumbers");
202
        $this->assertEquals(2, $count); // only 2 remaining
203
204
        // check that clear() removes the others via orphan removal
205
        $user->getPhonenumbers()->clear();
206
        $this->_em->flush();
207
        $this->assertEquals(0, $this->_em->getConnection()->fetchColumn("select count(*) from cms_phonenumbers"));
208
    }
209
210
    public function testBasicQuery()
211
    {
212
        $user = new CmsUser;
213
        $user->name = 'Guilherme';
214
        $user->username = 'gblanco';
215
        $user->status = 'developer';
216
        $this->_em->persist($user);
217
        $this->_em->flush();
218
219
        $query = $this->_em->createQuery("select u from Doctrine\Tests\Models\CMS\CmsUser u");
220
221
        $users = $query->getResult();
222
223
        $this->assertEquals(1, count($users));
224
        $this->assertEquals('Guilherme', $users[0]->name);
225
        $this->assertEquals('gblanco', $users[0]->username);
226
        $this->assertEquals('developer', $users[0]->status);
227
        //$this->assertNull($users[0]->phonenumbers);
228
        //$this->assertNull($users[0]->articles);
229
230
        $usersArray = $query->getArrayResult();
231
232
        $this->assertTrue(is_array($usersArray));
233
        $this->assertEquals(1, count($usersArray));
234
        $this->assertEquals('Guilherme', $usersArray[0]['name']);
235
        $this->assertEquals('gblanco', $usersArray[0]['username']);
236
        $this->assertEquals('developer', $usersArray[0]['status']);
237
238
        $usersScalar = $query->getScalarResult();
239
240
        $this->assertTrue(is_array($usersScalar));
241
        $this->assertEquals(1, count($usersScalar));
242
        $this->assertEquals('Guilherme', $usersScalar[0]['u_name']);
243
        $this->assertEquals('gblanco', $usersScalar[0]['u_username']);
244
        $this->assertEquals('developer', $usersScalar[0]['u_status']);
245
    }
246
247
    public function testBasicOneToManyInnerJoin()
248
    {
249
        $user = new CmsUser;
250
        $user->name = 'Guilherme';
251
        $user->username = 'gblanco';
252
        $user->status = 'developer';
253
        $this->_em->persist($user);
254
        $this->_em->flush();
255
256
        $query = $this->_em->createQuery("select u from Doctrine\Tests\Models\CMS\CmsUser u join u.phonenumbers p");
257
258
        $users = $query->getResult();
259
260
        $this->assertEquals(0, count($users));
261
    }
262
263
    public function testBasicOneToManyLeftJoin()
264
    {
265
        $user = new CmsUser;
266
        $user->name = 'Guilherme';
267
        $user->username = 'gblanco';
268
        $user->status = 'developer';
269
        $this->_em->persist($user);
270
        $this->_em->flush();
271
272
        $query = $this->_em->createQuery("select u,p from Doctrine\Tests\Models\CMS\CmsUser u left join u.phonenumbers p");
273
274
        $users = $query->getResult();
275
276
        $this->assertEquals(1, count($users));
277
        $this->assertEquals('Guilherme', $users[0]->name);
278
        $this->assertEquals('gblanco', $users[0]->username);
279
        $this->assertEquals('developer', $users[0]->status);
280
        $this->assertInstanceOf(PersistentCollection::class, $users[0]->phonenumbers);
281
        $this->assertTrue($users[0]->phonenumbers->isInitialized());
282
        $this->assertEquals(0, $users[0]->phonenumbers->count());
283
    }
284
285
    public function testBasicRefresh()
286
    {
287
        $user = new CmsUser;
288
        $user->name = 'Guilherme';
289
        $user->username = 'gblanco';
290
        $user->status = 'developer';
291
292
        $this->_em->persist($user);
293
        $this->_em->flush();
294
295
        $user->status = 'mascot';
296
297
        $this->assertEquals('mascot', $user->status);
298
        $this->_em->refresh($user);
299
        $this->assertEquals('developer', $user->status);
300
    }
301
302
    /**
303
     * @group DDC-833
304
     */
305
    public function testRefreshResetsCollection()
306
    {
307
        $user = new CmsUser;
308
        $user->name = 'Guilherme';
309
        $user->username = 'gblanco';
310
        $user->status = 'developer';
311
312
        // Add a phonenumber
313
        $ph1 = new CmsPhonenumber;
314
        $ph1->phonenumber = "12345";
315
        $user->addPhonenumber($ph1);
316
317
        // Add a phonenumber
318
        $ph2 = new CmsPhonenumber;
319
        $ph2->phonenumber = "54321";
320
321
        $this->_em->persist($user);
322
        $this->_em->persist($ph1);
323
        $this->_em->persist($ph2);
324
        $this->_em->flush();
325
326
        $user->addPhonenumber($ph2);
327
328
        $this->assertEquals(2, count($user->phonenumbers));
329
        $this->_em->refresh($user);
330
331
        $this->assertEquals(1, count($user->phonenumbers));
332
    }
333
334
    /**
335
     * @group DDC-833
336
     */
337
    public function testDqlRefreshResetsCollection()
338
    {
339
        $user = new CmsUser;
340
        $user->name = 'Guilherme';
341
        $user->username = 'gblanco';
342
        $user->status = 'developer';
343
344
        // Add a phonenumber
345
        $ph1 = new CmsPhonenumber;
346
        $ph1->phonenumber = "12345";
347
        $user->addPhonenumber($ph1);
348
349
        // Add a phonenumber
350
        $ph2 = new CmsPhonenumber;
351
        $ph2->phonenumber = "54321";
352
353
        $this->_em->persist($user);
354
        $this->_em->persist($ph1);
355
        $this->_em->persist($ph2);
356
        $this->_em->flush();
357
358
        $user->addPhonenumber($ph2);
359
360
        $this->assertEquals(2, count($user->phonenumbers));
361
        $dql = "SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.id = ?1";
362
        $user = $this->_em->createQuery($dql)
363
                          ->setParameter(1, $user->id)
364
                          ->setHint(Query::HINT_REFRESH, true)
365
                          ->getSingleResult();
366
367
        $this->assertEquals(1, count($user->phonenumbers));
368
    }
369
370
    /**
371
     * @group DDC-833
372
     */
373
    public function testCreateEntityOfProxy()
374
    {
375
        $user = new CmsUser;
376
        $user->name = 'Guilherme';
377
        $user->username = 'gblanco';
378
        $user->status = 'developer';
379
380
        // Add a phonenumber
381
        $ph1 = new CmsPhonenumber;
382
        $ph1->phonenumber = "12345";
383
        $user->addPhonenumber($ph1);
384
385
        // Add a phonenumber
386
        $ph2 = new CmsPhonenumber;
387
        $ph2->phonenumber = "54321";
388
389
        $this->_em->persist($user);
390
        $this->_em->persist($ph1);
391
        $this->_em->persist($ph2);
392
        $this->_em->flush();
393
        $this->_em->clear();
394
395
        $userId = $user->id;
396
        $user = $this->_em->getReference(CmsUser::class, $user->id);
397
398
        $dql = "SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.id = ?1";
399
        $user = $this->_em->createQuery($dql)
400
                          ->setParameter(1, $userId)
401
                          ->getSingleResult();
402
403
        $this->assertEquals(1, count($user->phonenumbers));
404
    }
405
406
    public function testAddToCollectionDoesNotInitialize()
407
    {
408
        $user = new CmsUser;
409
        $user->name = 'Guilherme';
410
        $user->username = 'gblanco';
411
        $user->status = 'developer';
412
413
        for ($i=0; $i<3; ++$i) {
414
            $phone = new CmsPhonenumber;
415
            $phone->phonenumber = 100 + $i;
416
            $user->addPhonenumber($phone);
417
        }
418
419
        $this->_em->persist($user);
420
        $this->_em->flush();
421
        $this->_em->clear();
422
423
        $this->assertEquals(3, $user->getPhonenumbers()->count());
424
425
        $query = $this->_em->createQuery("select u from Doctrine\Tests\Models\CMS\CmsUser u where u.username='gblanco'");
426
427
        $gblanco = $query->getSingleResult();
428
429
        $this->assertFalse($gblanco->getPhonenumbers()->isInitialized());
430
431
        $newPhone = new CmsPhonenumber;
432
        $newPhone->phonenumber = 555;
433
        $gblanco->addPhonenumber($newPhone);
434
435
        $this->assertFalse($gblanco->getPhonenumbers()->isInitialized());
436
        $this->_em->persist($gblanco);
437
438
        $this->_em->flush();
439
        $this->_em->clear();
440
441
        $query = $this->_em->createQuery("select u, p from Doctrine\Tests\Models\CMS\CmsUser u join u.phonenumbers p where u.username='gblanco'");
442
        $gblanco2 = $query->getSingleResult();
443
        $this->assertEquals(4, $gblanco2->getPhonenumbers()->count());
444
    }
445
446
    public function testInitializeCollectionWithNewObjectsRetainsNewObjects()
447
    {
448
        $user = new CmsUser;
449
        $user->name = 'Guilherme';
450
        $user->username = 'gblanco';
451
        $user->status = 'developer';
452
453
        for ($i=0; $i<3; ++$i) {
454
            $phone = new CmsPhonenumber;
455
            $phone->phonenumber = 100 + $i;
456
            $user->addPhonenumber($phone);
457
        }
458
459
        $this->_em->persist($user);
460
        $this->_em->flush();
461
        $this->_em->clear();
462
463
        $this->assertEquals(3, $user->getPhonenumbers()->count());
464
465
        $query = $this->_em->createQuery("select u from Doctrine\Tests\Models\CMS\CmsUser u where u.username='gblanco'");
466
467
        $gblanco = $query->getSingleResult();
468
469
        $this->assertFalse($gblanco->getPhonenumbers()->isInitialized());
470
471
        $newPhone = new CmsPhonenumber;
472
        $newPhone->phonenumber = 555;
473
        $gblanco->addPhonenumber($newPhone);
474
475
        $this->assertFalse($gblanco->getPhonenumbers()->isInitialized());
476
        $this->assertEquals(4, $gblanco->getPhonenumbers()->count());
477
        $this->assertTrue($gblanco->getPhonenumbers()->isInitialized());
478
479
        $this->_em->flush();
480
        $this->_em->clear();
481
482
        $query = $this->_em->createQuery("select u, p from Doctrine\Tests\Models\CMS\CmsUser u join u.phonenumbers p where u.username='gblanco'");
483
        $gblanco2 = $query->getSingleResult();
484
        $this->assertEquals(4, $gblanco2->getPhonenumbers()->count());
485
    }
486
487
    public function testSetSetAssociationWithGetReference()
488
    {
489
        $user = new CmsUser;
490
        $user->name = 'Guilherme';
491
        $user->username = 'gblanco';
492
        $user->status = 'developer';
493
        $this->_em->persist($user);
494
495
        $address = new CmsAddress;
496
        $address->country = 'Germany';
497
        $address->city = 'Berlin';
498
        $address->zip = '12345';
499
        $this->_em->persist($address);
500
501
        $this->_em->flush();
502
        $this->_em->detach($address);
503
504
        $this->assertFalse($this->_em->contains($address));
505
        $this->assertTrue($this->_em->contains($user));
506
507
        // Assume we only got the identifier of the address and now want to attach
508
        // that address to the user without actually loading it, using getReference().
509
        $addressRef = $this->_em->getReference(CmsAddress::class, $address->getId());
510
511
        $user->setAddress($addressRef); // Ugh! Initializes address 'cause of $address->setUser($user)!
512
513
        $this->_em->flush();
514
        $this->_em->clear();
515
516
        // Check with a fresh load that the association is indeed there
517
        $query = $this->_em->createQuery("select u, a from Doctrine\Tests\Models\CMS\CmsUser u join u.address a where u.username='gblanco'");
518
        $gblanco = $query->getSingleResult();
519
520
        $this->assertInstanceOf(CmsUser::class, $gblanco);
521
        $this->assertInstanceOf(CmsAddress::class, $gblanco->getAddress());
522
        $this->assertEquals('Berlin', $gblanco->getAddress()->getCity());
523
524
    }
525
526
    public function testOneToManyCascadeRemove()
527
    {
528
        $user = new CmsUser;
529
        $user->name = 'Guilherme';
530
        $user->username = 'gblanco';
531
        $user->status = 'developer';
532
533
        for ($i=0; $i<3; ++$i) {
534
            $phone = new CmsPhonenumber;
535
            $phone->phonenumber = 100 + $i;
536
            $user->addPhonenumber($phone);
537
        }
538
539
        $this->_em->persist($user);
540
        $this->_em->flush();
541
        $this->_em->clear();
542
543
        $query = $this->_em->createQuery("select u from Doctrine\Tests\Models\CMS\CmsUser u where u.username='gblanco'");
544
        $gblanco = $query->getSingleResult();
545
546
        $this->_em->remove($gblanco);
547
        $this->_em->flush();
548
549
        $this->_em->clear();
550
551
        $this->assertEquals(0, $this->_em->createQuery(
552
                "select count(p.phonenumber) from Doctrine\Tests\Models\CMS\CmsPhonenumber p")
553
                ->getSingleScalarResult());
554
555
        $this->assertEquals(0, $this->_em->createQuery(
556
                "select count(u.id) from Doctrine\Tests\Models\CMS\CmsUser u")
557
                ->getSingleScalarResult());
558
    }
559
560
    public function testTextColumnSaveAndRetrieve()
561
    {
562
        $user = new CmsUser;
563
        $user->name = 'Guilherme';
564
        $user->username = 'gblanco';
565
        $user->status = 'developer';
566
567
        $this->_em->persist($user);
568
569
        $article = new CmsArticle();
570
        $article->text = "Lorem ipsum dolor sunt.";
571
        $article->topic = "A Test Article!";
572
        $article->setAuthor($user);
573
574
        $this->_em->persist($article);
575
        $this->_em->flush();
576
        $articleId = $article->id;
577
578
        $this->_em->clear();
579
580
        // test find() with leading backslash at the same time
581
        $articleNew = $this->_em->find('\Doctrine\Tests\Models\CMS\CmsArticle', $articleId);
582
        $this->assertTrue($this->_em->contains($articleNew));
583
        $this->assertEquals("Lorem ipsum dolor sunt.", $articleNew->text);
584
585
        $this->assertNotSame($article, $articleNew);
586
587
        $articleNew->text = "Lorem ipsum dolor sunt. And stuff!";
588
589
        $this->_em->flush();
590
        $this->_em->clear();
591
592
        $articleNew = $this->_em->find(CmsArticle::class, $articleId);
593
        $this->assertEquals("Lorem ipsum dolor sunt. And stuff!", $articleNew->text);
594
        $this->assertTrue($this->_em->contains($articleNew));
595
    }
596
597
    public function testFlushDoesNotIssueUnnecessaryUpdates()
598
    {
599
        $user = new CmsUser;
600
        $user->name = 'Guilherme';
601
        $user->username = 'gblanco';
602
        $user->status = 'developer';
603
604
        $address = new CmsAddress;
605
        $address->country = 'Germany';
606
        $address->city = 'Berlin';
607
        $address->zip = '12345';
608
609
        $address->user = $user;
610
        $user->address = $address;
611
612
        $article = new CmsArticle();
613
        $article->text = "Lorem ipsum dolor sunt.";
614
        $article->topic = "A Test Article!";
615
        $article->setAuthor($user);
616
617
        $this->_em->persist($article);
618
        $this->_em->persist($user);
619
620
        //$this->_em->getConnection()->getConfiguration()->setSQLLogger(new \Doctrine\DBAL\Logging\EchoSQLLogger);
621
622
        $this->_em->flush();
623
        $this->_em->clear();
624
625
        $query = $this->_em->createQuery('select u,a,ad from Doctrine\Tests\Models\CMS\CmsUser u join u.articles a join u.address ad');
626
        $user2 = $query->getSingleResult();
627
628
        $this->assertEquals(1, count($user2->articles));
629
        $this->assertInstanceOf(CmsAddress::class, $user2->address);
630
631
        $oldLogger = $this->_em->getConnection()->getConfiguration()->getSQLLogger();
632
        $debugStack = new DebugStack();
633
        $this->_em->getConnection()->getConfiguration()->setSQLLogger($debugStack);
634
635
        $this->_em->flush();
636
        $this->assertEquals(0, count($debugStack->queries));
637
638
        $this->_em->getConnection()->getConfiguration()->setSQLLogger($oldLogger);
639
    }
640
641
    public function testRemoveEntityByReference()
642
    {
643
        $user = new CmsUser;
644
        $user->name = 'Guilherme';
645
        $user->username = 'gblanco';
646
        $user->status = 'developer';
647
648
        //$this->_em->getConnection()->getConfiguration()->setSQLLogger(new \Doctrine\DBAL\Logging\EchoSQLLogger);
649
650
        $this->_em->persist($user);
651
        $this->_em->flush();
652
        $this->_em->clear();
653
654
        $userRef = $this->_em->getReference(CmsUser::class, $user->getId());
655
        $this->_em->remove($userRef);
656
        $this->_em->flush();
657
        $this->_em->clear();
658
659
        $this->assertEquals(0, $this->_em->getConnection()->fetchColumn("select count(*) from cms_users"));
660
661
        //$this->_em->getConnection()->getConfiguration()->setSQLLogger(null);
662
    }
663
664
    public function testQueryEntityByReference()
665
    {
666
        $user = new CmsUser;
667
        $user->name = 'Guilherme';
668
        $user->username = 'gblanco';
669
        $user->status = 'developer';
670
671
        $address = new CmsAddress;
672
        $address->country = 'Germany';
673
        $address->city = 'Berlin';
674
        $address->zip = '12345';
675
676
        $user->setAddress($address);
677
678
        $this->_em->transactional(function($em) use($user) {
679
            $em->persist($user);
680
        });
681
        $this->_em->clear();
682
683
        //$this->_em->getConnection()->getConfiguration()->setSQLLogger(new \Doctrine\DBAL\Logging\EchoSQLLogger);
684
685
        $userRef = $this->_em->getReference(CmsUser::class, $user->getId());
686
        $address2 = $this->_em->createQuery('select a from Doctrine\Tests\Models\CMS\CmsAddress a where a.user = :user')
687
                ->setParameter('user', $userRef)
688
                ->getSingleResult();
689
690
        $this->assertInstanceOf(Proxy::class, $address2->getUser());
691
        $this->assertTrue($userRef === $address2->getUser());
692
        $this->assertFalse($userRef->__isInitialized__);
693
        $this->assertEquals('Germany', $address2->country);
694
        $this->assertEquals('Berlin', $address2->city);
695
        $this->assertEquals('12345', $address2->zip);
696
    }
697
698
    public function testOneToOneNullUpdate()
699
    {
700
        $user = new CmsUser();
701
        $user->username = "beberlei";
702
        $user->name = "Benjamin E.";
703
        $user->status = 'active';
704
705
        $address = new CmsAddress();
706
        $address->city = "Bonn";
707
        $address->zip = "12354";
708
        $address->country = "Germany";
709
        $address->street = "somestreet";
710
        $address->user = $user;
711
712
        $this->_em->persist($address);
713
        $this->_em->persist($user);
714
        $this->_em->flush();
715
716
        $this->assertEquals(1, $this->_em->getConnection()->fetchColumn("select 1 from cms_addresses where user_id = ".$user->id));
717
718
        $address->user = null;
719
        $this->_em->flush();
720
721
        $this->assertNotEquals(1, $this->_em->getConnection()->fetchColumn("select 1 from cms_addresses where user_id = ".$user->id));
722
    }
723
724
    /**
725
     * @group DDC-600
726
     * @group DDC-455
727
     */
728
    public function testNewAssociatedEntityDuringFlushThrowsException()
729
    {
730
        $this->expectException(\InvalidArgumentException::class);
731
732
        $user = new CmsUser();
733
        $user->username = "beberlei";
734
        $user->name = "Benjamin E.";
735
        $user->status = 'active';
736
737
        $address = new CmsAddress();
738
        $address->city = "Bonn";
739
        $address->zip = "12354";
740
        $address->country = "Germany";
741
        $address->street = "somestreet";
742
        $address->user = $user;
743
744
        $this->_em->persist($address);
745
746
        // flushing without persisting $user should raise an exception
747
        $this->_em->flush();
748
    }
749
750
    /**
751
     * @group DDC-600
752
     * @group DDC-455
753
     */
754
    public function testNewAssociatedEntityDuringFlushThrowsException2()
755
    {
756
        $this->expectException(\InvalidArgumentException::class);
757
758
        $user = new CmsUser();
759
        $user->username = "beberlei";
760
        $user->name = "Benjamin E.";
761
        $user->status = 'active';
762
763
        $address = new CmsAddress();
764
        $address->city = "Bonn";
765
        $address->zip = "12354";
766
        $address->country = "Germany";
767
        $address->street = "somestreet";
768
        $address->user = $user;
769
770
        $this->_em->persist($address);
771
        $this->_em->persist($user);
772
        $this->_em->flush();
773
774
        $u2 = new CmsUser;
775
        $u2->username = "beberlei";
776
        $u2->name = "Benjamin E.";
777
        $u2->status = 'inactive';
778
        $address->user = $u2;
779
780
        // flushing without persisting $u2 should raise an exception
781
        $this->_em->flush();
782
    }
783
784
    /**
785
     * @group DDC-600
786
     * @group DDC-455
787
     */
788
    public function testNewAssociatedEntityDuringFlushThrowsException3()
789
    {
790
        $this->expectException(\InvalidArgumentException::class);
791
792
        $art = new CmsArticle();
793
        $art->topic = 'topic';
794
        $art->text = 'the text';
795
796
        $com = new CmsComment();
797
        $com->topic = 'Good';
798
        $com->text = 'Really good!';
799
        $art->addComment($com);
800
801
        $this->_em->persist($art);
802
803
        // flushing without persisting $com should raise an exception
804
        $this->_em->flush();
805
    }
806
807
    public function testOneToOneOrphanRemoval()
808
    {
809
        $user = new CmsUser();
810
        $user->username = "beberlei";
811
        $user->name = "Benjamin E.";
812
        $user->status = 'active';
813
814
        $address = new CmsAddress();
815
        $address->city = "Bonn";
816
        $address->zip = "12354";
817
        $address->country = "Germany";
818
        $address->street = "somestreet";
819
        $address->user = $user;
820
        $user->address = $address;
821
822
        $this->_em->persist($address);
823
        $this->_em->persist($user);
824
        $this->_em->flush();
825
        $addressId = $address->getId();
826
827
        $user->address = null;
828
829
        $this->_em->flush();
830
831
        $this->assertEquals(0, $this->_em->getConnection()->fetchColumn("select count(*) from cms_addresses"));
832
833
        // check orphan removal through replacement
834
        $user->address = $address;
835
        $address->user = $user;
836
837
        $this->_em->flush();
838
        $this->assertEquals(1, $this->_em->getConnection()->fetchColumn("select count(*) from cms_addresses"));
839
840
        // remove $address to free up unique key id
841
        $this->_em->remove($address);
842
        $this->_em->flush();
843
844
        $newAddress = new CmsAddress();
845
        $newAddress->city = "NewBonn";
846
        $newAddress->zip = "12354";
847
        $newAddress->country = "NewGermany";
848
        $newAddress->street = "somenewstreet";
849
        $newAddress->user = $user;
850
        $user->address = $newAddress;
851
852
        $this->_em->flush();
853
        $this->assertEquals(1, $this->_em->getConnection()->fetchColumn("select count(*) from cms_addresses"));
854
    }
855
856
    public function testGetPartialReferenceToUpdateObjectWithoutLoadingIt()
857
    {
858
        $user = new CmsUser();
859
        $user->username = "beberlei";
860
        $user->name = "Benjamin E.";
861
        $user->status = 'active';
862
        $this->_em->persist($user);
863
        $this->_em->flush();
864
        $userId = $user->id;
865
        $this->_em->clear();
866
867
        $user = $this->_em->getPartialReference(CmsUser::class, $userId);
868
        $this->assertTrue($this->_em->contains($user));
869
        $this->assertNull($user->getName());
870
        $this->assertEquals($userId, $user->id);
871
872
        $user->name = 'Stephan';
873
        $this->_em->flush();
874
        $this->_em->clear();
875
876
        $this->assertEquals('Benjamin E.', $this->_em->find(get_class($user), $userId)->name);
877
    }
878
879
    public function testMergePersistsNewEntities()
880
    {
881
        $user = new CmsUser();
882
        $user->username = "beberlei";
883
        $user->name = "Benjamin E.";
884
        $user->status = 'active';
885
886
        $managedUser = $this->_em->merge($user);
887
        $this->assertEquals('beberlei', $managedUser->username);
888
        $this->assertEquals('Benjamin E.', $managedUser->name);
889
        $this->assertEquals('active', $managedUser->status);
890
891
        $this->assertTrue($user !== $managedUser);
892
        $this->assertTrue($this->_em->contains($managedUser));
893
894
        $this->_em->flush();
895
        $userId = $managedUser->id;
896
        $this->_em->clear();
897
898
        $user2 = $this->_em->find(get_class($managedUser), $userId);
899
        $this->assertInstanceOf(CmsUser::class, $user2);
900
    }
901
902
    public function testMergeNonPersistedProperties()
903
    {
904
        $user = new CmsUser();
905
        $user->username = "beberlei";
906
        $user->name = "Benjamin E.";
907
        $user->status = 'active';
908
        $user->nonPersistedProperty = 'test';
909
        $user->nonPersistedPropertyObject = new CmsPhonenumber();
910
911
        $managedUser = $this->_em->merge($user);
912
        $this->assertEquals('test', $managedUser->nonPersistedProperty);
913
        $this->assertSame($user->nonPersistedProperty, $managedUser->nonPersistedProperty);
914
        $this->assertSame($user->nonPersistedPropertyObject, $managedUser->nonPersistedPropertyObject);
915
916
        $this->assertTrue($user !== $managedUser);
917
        $this->assertTrue($this->_em->contains($managedUser));
918
919
        $this->_em->flush();
920
        $userId = $managedUser->id;
921
        $this->_em->clear();
922
923
        $user2 = $this->_em->find(get_class($managedUser), $userId);
924
        $this->assertNull($user2->nonPersistedProperty);
925
        $this->assertNull($user2->nonPersistedPropertyObject);
926
        $this->assertEquals('active', $user2->status);
927
    }
928
929
    public function testMergeThrowsExceptionIfEntityWithGeneratedIdentifierDoesNotExist()
930
    {
931
        $this->expectException(EntityNotFoundException::class);
932
933
        $user = new CmsUser();
934
        $user->username = "beberlei";
935
        $user->name = "Benjamin E.";
936
        $user->status = 'active';
937
        $user->id = 42;
938
939
        $this->_em->merge($user);
940
    }
941
942
    /**
943
     * @group DDC-634
944
     */
945
    public function testOneToOneMergeSetNull()
946
    {
947
        $user = new CmsUser();
948
        $user->username = "beberlei";
949
        $user->name = "Benjamin E.";
950
        $user->status = 'active';
951
952
        $ph = new CmsPhonenumber();
953
        $ph->phonenumber = "12345";
954
        $user->addPhonenumber($ph);
955
956
        $this->_em->persist($user);
957
        $this->_em->persist($ph);
958
        $this->_em->flush();
959
960
        $this->_em->clear();
961
962
        $ph->user = null;
963
        $managedPh = $this->_em->merge($ph);
964
965
        $this->_em->flush();
966
        $this->_em->clear();
967
968
        $this->assertNull($this->_em->find(get_class($ph), $ph->phonenumber)->getUser());
969
    }
970
971
    /**
972
     * @group DDC-952
973
     */
974
    public function testManyToOneFetchModeQuery()
975
    {
976
        $user = new CmsUser();
977
        $user->username = "beberlei";
978
        $user->name = "Benjamin E.";
979
        $user->status = 'active';
980
981
        $article = new CmsArticle();
982
        $article->topic = "foo";
983
        $article->text = "bar";
984
        $article->user = $user;
985
986
        $this->_em->persist($article);
987
        $this->_em->persist($user);
988
        $this->_em->flush();
989
        $this->_em->clear();
990
991
        $qc = $this->getCurrentQueryCount();
992
        $dql = "SELECT a FROM Doctrine\Tests\Models\CMS\CmsArticle a WHERE a.id = ?1";
993
        $article = $this->_em->createQuery($dql)
994
                             ->setParameter(1, $article->id)
995
                             ->setFetchMode(CmsArticle::class, 'user', ClassMetadata::FETCH_EAGER)
996
                             ->getSingleResult();
997
        $this->assertInstanceOf(Proxy::class, $article->user, "It IS a proxy, ...");
998
        $this->assertTrue($article->user->__isInitialized__, "...but its initialized!");
999
        $this->assertEquals($qc+2, $this->getCurrentQueryCount());
1000
    }
1001
1002
    /**
1003
     * @group DDC-1278
1004
     */
1005
    public function testClearWithEntityName()
1006
    {
1007
        $user = new CmsUser;
1008
        $user->name = 'Dominik';
1009
        $user->username = 'domnikl';
1010
        $user->status = 'developer';
1011
1012
        $address = new CmsAddress();
1013
        $address->city = "Springfield";
1014
        $address->zip = "12354";
1015
        $address->country = "Germany";
1016
        $address->street = "Foo Street";
1017
        $address->user = $user;
1018
        $user->address = $address;
1019
1020
        $article1 = new CmsArticle();
1021
        $article1->topic = 'Foo';
1022
        $article1->text = 'Foo Text';
1023
1024
        $article2 = new CmsArticle();
1025
        $article2->topic = 'Bar';
1026
        $article2->text = 'Bar Text';
1027
1028
        $user->addArticle($article1);
1029
        $user->addArticle($article2);
1030
1031
        $this->_em->persist($article1);
1032
        $this->_em->persist($article2);
1033
        $this->_em->persist($address);
1034
        $this->_em->persist($user);
1035
        $this->_em->flush();
1036
1037
        $unitOfWork = $this->_em->getUnitOfWork();
1038
1039
        $this->_em->clear(CmsUser::class);
1040
1041
        $this->assertEquals(UnitOfWork::STATE_DETACHED, $unitOfWork->getEntityState($user));
1042
        $this->assertEquals(UnitOfWork::STATE_DETACHED, $unitOfWork->getEntityState($article1));
1043
        $this->assertEquals(UnitOfWork::STATE_DETACHED, $unitOfWork->getEntityState($article2));
1044
        $this->assertEquals(UnitOfWork::STATE_MANAGED, $unitOfWork->getEntityState($address));
1045
1046
        $this->_em->clear();
1047
1048
        $this->assertEquals(UnitOfWork::STATE_DETACHED, $unitOfWork->getEntityState($address));
1049
    }
1050
1051
    public function testFlushManyExplicitEntities()
1052
    {
1053
        $userA = new CmsUser;
1054
        $userA->username = 'UserA';
1055
        $userA->name = 'UserA';
1056
1057
        $userB = new CmsUser;
1058
        $userB->username = 'UserB';
1059
        $userB->name = 'UserB';
1060
1061
        $userC = new CmsUser;
1062
        $userC->username = 'UserC';
1063
        $userC->name = 'UserC';
1064
1065
        $this->_em->persist($userA);
1066
        $this->_em->persist($userB);
1067
        $this->_em->persist($userC);
1068
1069
        $this->_em->flush([$userA, $userB, $userB]);
1070
1071
        $userC->name = 'changed name';
1072
1073
        $this->_em->flush([$userA, $userB]);
1074
        $this->_em->refresh($userC);
1075
1076
        $this->assertTrue($userA->id > 0, 'user a has an id');
1077
        $this->assertTrue($userB->id > 0, 'user b has an id');
1078
        $this->assertTrue($userC->id > 0, 'user c has an id');
1079
        $this->assertEquals('UserC', $userC->name, 'name has not changed because we did not flush it');
1080
    }
1081
1082
    /**
1083
     * @group DDC-720
1084
     */
1085
    public function testFlushSingleManagedEntity()
1086
    {
1087
        $user = new CmsUser;
1088
        $user->name = 'Dominik';
1089
        $user->username = 'domnikl';
1090
        $user->status = 'developer';
1091
1092
        $this->_em->persist($user);
1093
        $this->_em->flush();
1094
1095
        $user->status = 'administrator';
1096
        $this->_em->flush($user);
1097
        $this->_em->clear();
1098
1099
        $user = $this->_em->find(get_class($user), $user->id);
1100
        $this->assertEquals('administrator', $user->status);
1101
    }
1102
1103
    /**
1104
     * @group DDC-720
1105
     */
1106
    public function testFlushSingleUnmanagedEntity()
1107
    {
1108
        $user = new CmsUser;
1109
        $user->name = 'Dominik';
1110
        $user->username = 'domnikl';
1111
        $user->status = 'developer';
1112
1113
        $this->expectException(\InvalidArgumentException::class);
1114
        $this->expectExceptionMessage('Entity has to be managed or scheduled for removal for single computation');
1115
1116
        $this->_em->flush($user);
1117
    }
1118
1119
    /**
1120
     * @group DDC-720
1121
     */
1122
    public function testFlushSingleAndNewEntity()
1123
    {
1124
        $user = new CmsUser;
1125
        $user->name = 'Dominik';
1126
        $user->username = 'domnikl';
1127
        $user->status = 'developer';
1128
1129
        $this->_em->persist($user);
1130
        $this->_em->flush();
1131
1132
        $otherUser = new CmsUser;
1133
        $otherUser->name = 'Dominik2';
1134
        $otherUser->username = 'domnikl2';
1135
        $otherUser->status = 'developer';
1136
1137
        $user->status = 'administrator';
1138
1139
        $this->_em->persist($otherUser);
1140
        $this->_em->flush($user);
1141
1142
        $this->assertTrue($this->_em->contains($otherUser), "Other user is contained in EntityManager");
1143
        $this->assertTrue($otherUser->id > 0, "other user has an id");
1144
    }
1145
1146
    /**
1147
     * @group DDC-720
1148
     */
1149
    public function testFlushAndCascadePersist()
1150
    {
1151
        $user = new CmsUser;
1152
        $user->name = 'Dominik';
1153
        $user->username = 'domnikl';
1154
        $user->status = 'developer';
1155
1156
        $this->_em->persist($user);
1157
        $this->_em->flush();
1158
1159
        $address = new CmsAddress();
1160
        $address->city = "Springfield";
1161
        $address->zip = "12354";
1162
        $address->country = "Germany";
1163
        $address->street = "Foo Street";
1164
        $address->user = $user;
1165
        $user->address = $address;
1166
1167
        $this->_em->flush($user);
1168
1169
        $this->assertTrue($this->_em->contains($address), "Other user is contained in EntityManager");
1170
        $this->assertTrue($address->id > 0, "other user has an id");
1171
    }
1172
1173
    /**
1174
     * @group DDC-720
1175
     */
1176
    public function testFlushSingleAndNoCascade()
1177
    {
1178
        $user = new CmsUser;
1179
        $user->name = 'Dominik';
1180
        $user->username = 'domnikl';
1181
        $user->status = 'developer';
1182
1183
        $this->_em->persist($user);
1184
        $this->_em->flush();
1185
1186
        $article1 = new CmsArticle();
1187
        $article1->topic = 'Foo';
1188
        $article1->text = 'Foo Text';
1189
        $article1->author = $user;
1190
        $user->articles[] = $article1;
1191
1192
        $this->expectException(\InvalidArgumentException::class);
1193
        $this->expectExceptionMessage("A new entity was found through the relationship 'Doctrine\Tests\Models\CMS\CmsUser#articles'");
1194
1195
        $this->_em->flush($user);
1196
    }
1197
1198
    /**
1199
     * @group DDC-720
1200
     * @group DDC-1612
1201
     * @group DDC-2267
1202
     */
1203
    public function testFlushSingleNewEntityThenRemove()
1204
    {
1205
        $user = new CmsUser;
1206
        $user->name = 'Dominik';
1207
        $user->username = 'domnikl';
1208
        $user->status = 'developer';
1209
1210
        $this->_em->persist($user);
1211
        $this->_em->flush($user);
1212
1213
        $userId = $user->id;
1214
1215
        $this->_em->remove($user);
1216
        $this->_em->flush($user);
1217
        $this->_em->clear();
1218
1219
        $this->assertNull($this->_em->find(get_class($user), $userId));
1220
    }
1221
1222
    /**
1223
     * @group DDC-720
1224
     */
1225
    public function testProxyIsIgnored()
1226
    {
1227
        $user = new CmsUser;
1228
        $user->name = 'Dominik';
1229
        $user->username = 'domnikl';
1230
        $user->status = 'developer';
1231
1232
        $this->_em->persist($user);
1233
        $this->_em->flush();
1234
        $this->_em->clear();
1235
1236
        $user = $this->_em->getReference(get_class($user), $user->id);
1237
1238
        $otherUser = new CmsUser;
1239
        $otherUser->name = 'Dominik2';
1240
        $otherUser->username = 'domnikl2';
1241
        $otherUser->status = 'developer';
1242
1243
        $this->_em->persist($otherUser);
1244
        $this->_em->flush($user);
1245
1246
        $this->assertTrue($this->_em->contains($otherUser), "Other user is contained in EntityManager");
1247
        $this->assertTrue($otherUser->id > 0, "other user has an id");
1248
    }
1249
1250
    /**
1251
     * @group DDC-720
1252
     */
1253
    public function testFlushSingleSaveOnlySingle()
1254
    {
1255
        $user = new CmsUser;
1256
        $user->name = 'Dominik';
1257
        $user->username = 'domnikl';
1258
        $user->status = 'developer';
1259
        $this->_em->persist($user);
1260
1261
        $user2 = new CmsUser;
1262
        $user2->name = 'Dominik';
1263
        $user2->username = 'domnikl2';
1264
        $user2->status = 'developer';
1265
        $this->_em->persist($user2);
1266
1267
        $this->_em->flush();
1268
1269
        $user->status = 'admin';
1270
        $user2->status = 'admin';
1271
1272
        $this->_em->flush($user);
1273
        $this->_em->clear();
1274
1275
        $user2 = $this->_em->find(get_class($user2), $user2->id);
1276
        $this->assertEquals('developer', $user2->status);
1277
    }
1278
1279
    /**
1280
     * @group DDC-1585
1281
     */
1282
    public function testWrongAssociationInstance()
1283
    {
1284
        $user = new CmsUser;
1285
        $user->name = 'Dominik';
1286
        $user->username = 'domnikl';
1287
        $user->status = 'developer';
1288
        $user->address = $user;
1289
1290
        $this->expectException(ORMInvalidArgumentException::class);
1291
        $this->expectExceptionMessage(
1292
            'Expected value of type "Doctrine\Tests\Models\CMS\CmsAddress" for association field ' .
1293
            '"Doctrine\Tests\Models\CMS\CmsUser#$address", got "Doctrine\Tests\Models\CMS\CmsUser" instead.'
1294
        );
1295
1296
        $this->_em->persist($user);
1297
1298
        $this->_em->flush();
1299
    }
1300
}
1301