-
Notifications
You must be signed in to change notification settings - Fork 2.5k
Closed as not planned
Description
Bug Report
Doctrine fails to replace ArrayCollection with PersistentCollection for readonly properties. I assume this should be documented or bypassed (cannot imagine how).
Current docs states it should be possible.:
An entity class must not be final nor read-only but it may contain final methods or read-only properties.
Q | A |
---|---|
BC Break | no |
Version | 2.14.2 |
Current behavior
It throws exception, callstack:
LogicException : Attempting to change readonly property App\User::$accounts.
/opt/project/vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/ReflectionReadonlyProperty.php:46
/opt/project/vendor/doctrine/orm/lib/Doctrine/ORM/UnitOfWork.php:697
/opt/project/vendor/doctrine/orm/lib/Doctrine/ORM/UnitOfWork.php:528
/opt/project/vendor/doctrine/orm/lib/Doctrine/ORM/UnitOfWork.php:863
/opt/project/vendor/doctrine/orm/lib/Doctrine/ORM/UnitOfWork.php:377
/opt/project/vendor/doctrine/orm/lib/Doctrine/ORM/EntityManager.php:403
How to reproduce
Test:
<?php declare(strict_types = 1);
namespace App;
use Doctrine\ORM\Configuration;
use Doctrine\ORM\EntityManager;
use Doctrine\ORM\EntityManagerInterface;
use PHPUnit\Framework\TestCase;
class UseIndexSqlWalkerTest extends TestCase
{
public function createEntityManager(): EntityManagerInterface
{
$config = new Configuration();
$config->setProxyDir(sys_get_temp_dir());
$config->setProxyNamespace('MyProxies');
$config->setMetadataDriverImpl($config->newDefaultAnnotationDriver([__DIR__], false));
return EntityManager::create(['driver' => 'pdo_sqlite', 'memory' => true], $config);
}
public function testReadonlyCollection(): void {
$account = new Account();
$user = new User($account);
$em = $this->createEntityManager();
$em->persist($account);
$em->persist($user);
$em->flush();
}
}
Entities:
<?php declare(strict_types = 1);
namespace App;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;
/**
* @ORM\Entity
*/
class User
{
/**
* @ORM\Id
* @ORM\Column(type="string", nullable=false)
* @ORM\GeneratedValue
*/
public ?int $id;
/**
* @ORM\ManyToMany(targetEntity=Account::class)
*/
private readonly Collection $accounts;
public function __construct(Account $account)
{
$this->accounts = new ArrayCollection([$account]);
}
}
<?php declare(strict_types = 1);
namespace App;
use Doctrine\ORM\Mapping as ORM;
/**
* @ORM\Entity
*/
class Account
{
/**
* @ORM\Id
* @ORM\Column(type="string", nullable=false)
* @ORM\GeneratedValue
*/
public ?int $id;
}
Expected behavior
No failure
sc0rp10
Metadata
Metadata
Assignees
Labels
No labels