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
|
<?php
declare(strict_types=1);
namespace Doctrine\Tests\ORM\Functional\Ticket;
use DateTime;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping\Column;
use Doctrine\ORM\Mapping\Entity;
use Doctrine\ORM\Mapping\GeneratedValue;
use Doctrine\ORM\Mapping\HasLifecycleCallbacks;
use Doctrine\ORM\Mapping\Id;
use Doctrine\ORM\Mapping\JoinColumn;
use Doctrine\ORM\Mapping\OneToMany;
use Doctrine\ORM\Mapping\OneToOne;
use Doctrine\ORM\Mapping\PrePersist;
use Doctrine\ORM\Mapping\PreUpdate;
use Doctrine\ORM\Mapping\Table;
use Doctrine\ORM\Mapping\UniqueConstraint;
use Doctrine\Tests\OrmFunctionalTestCase;
class DDC345Test extends OrmFunctionalTestCase
{
protected function setUp(): void
{
parent::setUp();
$this->createSchemaForModels(
DDC345User::class,
DDC345Group::class,
DDC345Membership::class,
);
}
public function testTwoIterateHydrations(): void
{
// Create User
$user = new DDC345User();
$user->name = 'Test User';
$this->_em->persist($user); // $em->flush() does not change much here
// Create Group
$group = new DDC345Group();
$group->name = 'Test Group';
$this->_em->persist($group); // $em->flush() does not change much here
$membership = new DDC345Membership();
$membership->group = $group;
$membership->user = $user;
$membership->state = 'active';
//$this->_em->persist($membership); // COMMENT OUT TO SEE BUG
/*
This should be not necessary, but without, its PrePersist is called twice,
$membership seems to be persisted twice, but all properties but the
ones set by LifecycleCallbacks are deleted.
*/
$user->memberships->add($membership);
$group->memberships->add($membership);
$this->_em->flush();
self::assertEquals(1, $membership->prePersistCallCount);
self::assertEquals(0, $membership->preUpdateCallCount);
self::assertInstanceOf(DateTime::class, $membership->updated);
}
}
#[Entity]
class DDC345User
{
/** @var int */
#[Id]
#[Column(type: 'integer')]
#[GeneratedValue]
public $id;
/** @var string */
#[Column(type: 'string', length: 255)]
public $name;
/** @phpstan-var Collection<int, DDC345Membership> */
#[OneToMany(targetEntity: 'DDC345Membership', mappedBy: 'user', cascade: ['persist'])]
public $memberships;
public function __construct()
{
$this->memberships = new ArrayCollection();
}
}
#[Entity]
class DDC345Group
{
/** @var int */
#[Id]
#[Column(type: 'integer')]
#[GeneratedValue]
public $id;
/** @var string */
#[Column(type: 'string', length: 255)]
public $name;
/** @phpstan-var Collection<int, DDC345Membership> */
#[OneToMany(targetEntity: 'DDC345Membership', mappedBy: 'group', cascade: ['persist'])]
public $memberships;
public function __construct()
{
$this->memberships = new ArrayCollection();
}
}
#[Table(name: 'ddc345_memberships')]
#[UniqueConstraint(name: 'ddc345_memship_fks', columns: ['user_id', 'group_id'])]
#[Entity]
#[HasLifecycleCallbacks]
class DDC345Membership
{
/** @var int */
#[Id]
#[Column(type: 'integer')]
#[GeneratedValue]
public $id;
/** @var DDC345User */
#[OneToOne(targetEntity: 'DDC345User', inversedBy: 'memberships')]
#[JoinColumn(name: 'user_id', referencedColumnName: 'id', nullable: false)]
public $user;
/** @var DDC345Group */
#[OneToOne(targetEntity: 'DDC345Group', inversedBy: 'memberships')]
#[JoinColumn(name: 'group_id', referencedColumnName: 'id', nullable: false)]
public $group;
/** @var string */
#[Column(type: 'string', length: 255)]
public $state;
/** @var DateTime */
#[Column(type: 'datetime')]
public $updated;
/** @var int */
public $prePersistCallCount = 0;
/** @var int */
public $preUpdateCallCount = 0;
#[PrePersist]
public function doStuffOnPrePersist(): void
{
//echo "***** PrePersist\n";
++$this->prePersistCallCount;
$this->updated = new DateTime();
}
#[PreUpdate]
public function doStuffOnPreUpdate(): void
{
//echo "***** PreUpdate\n";
++$this->preUpdateCallCount;
$this->updated = new DateTime();
}
}
|