diff --git a/psalm-baseline.xml b/psalm-baseline.xml
index 7a3b729e849..d191c3782ff 100644
--- a/psalm-baseline.xml
+++ b/psalm-baseline.xml
@@ -1502,7 +1502,9 @@
-
+
diff --git a/src/Proxy/ProxyFactory.php b/src/Proxy/ProxyFactory.php
index 5b2d2eca0c9..dc8a72bfcea 100644
--- a/src/Proxy/ProxyFactory.php
+++ b/src/Proxy/ProxyFactory.php
@@ -354,15 +354,14 @@ private function createInitializer(ClassMetadata $classMetadata, EntityPersister
/**
* Creates a closure capable of initializing a proxy
*
- * @return Closure(InternalProxy, InternalProxy):void
+ * @return Closure(InternalProxy, array):void
*
* @throws EntityNotFoundException
*/
private function createLazyInitializer(ClassMetadata $classMetadata, EntityPersister $entityPersister, IdentifierFlattener $identifierFlattener): Closure
{
- return static function (InternalProxy $proxy) use ($entityPersister, $classMetadata, $identifierFlattener): void {
- $identifier = $classMetadata->getIdentifierValues($proxy);
- $original = $entityPersister->loadById($identifier);
+ return static function (InternalProxy $proxy, array $identifier) use ($entityPersister, $classMetadata, $identifierFlattener): void {
+ $original = $entityPersister->loadById($identifier);
if ($original === null) {
throw EntityNotFoundException::fromClassNameAndIdentifier(
@@ -378,7 +377,7 @@ private function createLazyInitializer(ClassMetadata $classMetadata, EntityPersi
$class = $entityPersister->getClassMetadata();
foreach ($class->getReflectionProperties() as $property) {
- if (! $class->hasField($property->name) && ! $class->hasAssociation($property->name)) {
+ if (isset($identifier[$property->name]) || ! $class->hasField($property->name) && ! $class->hasAssociation($property->name)) {
continue;
}
@@ -468,7 +467,9 @@ private function getProxyFactory(string $className): Closure
$identifierFields = array_intersect_key($class->getReflectionProperties(), $identifiers);
$proxyFactory = Closure::bind(static function (array $identifier) use ($initializer, $skippedProperties, $identifierFields, $className): InternalProxy {
- $proxy = self::createLazyGhost($initializer, $skippedProperties);
+ $proxy = self::createLazyGhost(static function (InternalProxy $object) use ($initializer, $identifier): void {
+ $initializer($object, $identifier);
+ }, $skippedProperties);
foreach ($identifierFields as $idField => $reflector) {
if (! isset($identifier[$idField])) {
diff --git a/tests/Tests/Models/ECommerce/ECommerceProduct2.php b/tests/Tests/Models/ECommerce/ECommerceProduct2.php
new file mode 100644
index 00000000000..4d676ddc5fc
--- /dev/null
+++ b/tests/Tests/Models/ECommerce/ECommerceProduct2.php
@@ -0,0 +1,59 @@
+id;
+ }
+
+ public function getName(): string
+ {
+ return $this->name;
+ }
+
+ public function __clone()
+ {
+ $this->id = null;
+ $this->name = 'Clone of ' . $this->name;
+ }
+}
diff --git a/tests/Tests/ORM/Functional/ProxiesLikeEntitiesTest.php b/tests/Tests/ORM/Functional/ProxiesLikeEntitiesTest.php
index 01f82c8de7d..1cd05c3fc5a 100644
--- a/tests/Tests/ORM/Functional/ProxiesLikeEntitiesTest.php
+++ b/tests/Tests/ORM/Functional/ProxiesLikeEntitiesTest.php
@@ -58,7 +58,7 @@ protected function setUp(): void
public function testPersistUpdate(): void
{
// Considering case (a)
- $proxy = $this->_em->getProxyFactory()->getProxy(CmsUser::class, ['id' => 123]);
+ $proxy = $this->_em->getProxyFactory()->getProxy(CmsUser::class, ['id' => $this->user->getId()]);
$proxy->id = null;
$proxy->username = 'ocra';
diff --git a/tests/Tests/ORM/Functional/ReferenceProxyTest.php b/tests/Tests/ORM/Functional/ReferenceProxyTest.php
index 88c14253e20..bb4a2cfb36c 100644
--- a/tests/Tests/ORM/Functional/ReferenceProxyTest.php
+++ b/tests/Tests/ORM/Functional/ReferenceProxyTest.php
@@ -9,6 +9,7 @@
use Doctrine\ORM\Proxy\InternalProxy;
use Doctrine\Tests\Models\Company\CompanyAuction;
use Doctrine\Tests\Models\ECommerce\ECommerceProduct;
+use Doctrine\Tests\Models\ECommerce\ECommerceProduct2;
use Doctrine\Tests\Models\ECommerce\ECommerceShipping;
use Doctrine\Tests\OrmFunctionalTestCase;
@@ -112,6 +113,24 @@ public function testCloneProxy(): void
self::assertFalse($entity->isCloned);
}
+ public function testCloneProxyWithResetId(): void
+ {
+ $id = $this->createProduct();
+
+ $entity = $this->_em->getReference(ECommerceProduct2::class, $id);
+ assert($entity instanceof ECommerceProduct2);
+
+ $clone = clone $entity;
+ assert($clone instanceof ECommerceProduct2);
+
+ self::assertEquals($id, $entity->getId());
+ self::assertEquals('Doctrine Cookbook', $entity->getName());
+
+ self::assertFalse($this->_em->contains($clone));
+ self::assertNull($clone->getId());
+ self::assertEquals('Clone of Doctrine Cookbook', $clone->getName());
+ }
+
/** @group DDC-733 */
public function testInitializeProxy(): void
{