File: GH5742Test.php

package info (click to toggle)
doctrine 3.5.2%2Bdfsg-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 11,556 kB
  • sloc: php: 108,620; xml: 1,340; makefile: 35; sh: 14
file content (132 lines) | stat: -rw-r--r-- 4,017 bytes parent folder | download | duplicates (2)
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
<?php

declare(strict_types=1);

namespace Doctrine\Tests\ORM\Functional\Ticket;

use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;
use Doctrine\Tests\OrmFunctionalTestCase;

class GH5742Test extends OrmFunctionalTestCase
{
    protected function setUp(): void
    {
        parent::setUp();

        $this->createSchemaForModels(
            GH5742Person::class,
            GH5742Toothbrush::class,
            GH5742ToothpasteBrand::class,
        );
    }

    public function testUpdateOneToOneToNewEntityBeforePreviousEntityCanBeRemoved(): void
    {
        $person             = new GH5742Person();
        $oldToothbrush      = new GH5742Toothbrush();
        $person->toothbrush = $oldToothbrush;

        $this->_em->persist($person);
        $this->_em->persist($oldToothbrush);
        $this->_em->flush();

        $oldToothbrushId = $oldToothbrush->id;

        $newToothbrush      = new GH5742Toothbrush();
        $person->toothbrush = $newToothbrush;

        $this->_em->remove($oldToothbrush);
        $this->_em->persist($newToothbrush);

        // The flush operation will have to make sure the new toothbrush
        // has been written to the database
        // _before_ the person can be updated to refer to it.
        // Likewise, the update must have happened _before_ the old
        // toothbrush can be removed (non-nullable FK constraint).

        $this->_em->flush();

        $this->_em->clear();
        self::assertSame($newToothbrush->id, $this->_em->find(GH5742Person::class, $person->id)->toothbrush->id);
        self::assertNull($this->_em->find(GH5742Toothbrush::class, $oldToothbrushId));
    }

    public function testManyToManyCollectionUpdateBeforeRemoval(): void
    {
        $person             = new GH5742Person();
        $person->toothbrush = new GH5742Toothbrush(); // to satisfy not-null constraint
        $this->_em->persist($person);

        $oldMice = new GH5742ToothpasteBrand();
        $this->_em->persist($oldMice);

        $person->preferredBrands->set(1, $oldMice);
        $this->_em->flush();

        $oldBrandId = $oldMice->id;

        $newSpice = new GH5742ToothpasteBrand();
        $this->_em->persist($newSpice);

        $person->preferredBrands->set(1, $newSpice);

        $this->_em->remove($oldMice);

        // The flush operation will have to make sure the new brand
        // has been written to the database _before_ it can be referred
        // to from the m2m join table.
        // Likewise, the old join table entry must have been removed
        // _before_ the old brand can be removed.

        $this->_em->flush();

        $this->_em->clear();
        self::assertCount(1, $this->_em->find(GH5742Person::class, $person->id)->preferredBrands);
        self::assertNull($this->_em->find(GH5742ToothpasteBrand::class, $oldBrandId));
    }
}

#[ORM\Entity]
class GH5742Person
{
    #[ORM\Id]
    #[ORM\GeneratedValue(strategy: 'AUTO')]
    #[ORM\Column(type: 'integer')]
    public int $id;

    #[ORM\OneToOne(targetEntity: 'GH5742Toothbrush', cascade: ['persist'])]
    #[ORM\JoinColumn(nullable: false)]
    public GH5742Toothbrush $toothbrush;

    /** @var Collection<GH5742ToothpasteBrand> */
    #[ORM\ManyToMany(targetEntity: 'GH5742ToothpasteBrand')]
    #[ORM\JoinTable('gh5742person_gh5742toothpastebrand')]
    #[ORM\JoinColumn(name: 'person_id', referencedColumnName: 'id', onDelete: 'CASCADE')]
    #[ORM\InverseJoinColumn(name: 'brand_id', referencedColumnName: 'id')]
    public Collection $preferredBrands;

    public function __construct()
    {
        $this->preferredBrands = new ArrayCollection();
    }
}

#[ORM\Entity]
class GH5742Toothbrush
{
    #[ORM\Id]
    #[ORM\GeneratedValue(strategy: 'AUTO')]
    #[ORM\Column(type: 'integer')]
    public int $id;
}

#[ORM\Entity]
class GH5742ToothpasteBrand
{
    #[ORM\Id]
    #[ORM\GeneratedValue(strategy: 'AUTO')]
    #[ORM\Column(type: 'integer')]
    public int $id;
}