diff --git a/lib/Doctrine/ORM/UnitOfWork.php b/lib/Doctrine/ORM/UnitOfWork.php index 3ba860b8917..faa6650e287 100644 --- a/lib/Doctrine/ORM/UnitOfWork.php +++ b/lib/Doctrine/ORM/UnitOfWork.php @@ -1866,7 +1866,7 @@ private function doMerge($entity, array &$visited, $prevManagedCopy = null, $ass } } - if ($class->isVersioned) { + if ($class->isVersioned && $this->isLoaded($managedCopy) && $this->isLoaded($entity)) { $reflField = $class->reflFields[$class->versionField]; $managedCopyVersion = $reflField->getValue($managedCopy); $entityVersion = $reflField->getValue($entity); @@ -1879,7 +1879,7 @@ private function doMerge($entity, array &$visited, $prevManagedCopy = null, $ass $visited[$oid] = $managedCopy; // mark visited - if (!($entity instanceof Proxy && ! $entity->__isInitialized())) { + if ($this->isLoaded($entity)) { if ($managedCopy instanceof Proxy && ! $managedCopy->__isInitialized()) { $managedCopy->__load(); } @@ -1904,6 +1904,18 @@ private function doMerge($entity, array &$visited, $prevManagedCopy = null, $ass return $managedCopy; } + /** + * Tests if an entity is loaded (Not a proxy or a non initialized proxy) + * + * @param $entity + * + * @return bool + */ + private function isLoaded($entity) + { + return !($entity instanceof Proxy) || $entity->__isInitialized(); + } + /** * Sets/adds associated managed copies into the previous entity's association field * diff --git a/tests/Doctrine/Tests/Models/VersionedOneToMany/Article.php b/tests/Doctrine/Tests/Models/VersionedOneToMany/Article.php new file mode 100644 index 00000000000..bd0cfdf4803 --- /dev/null +++ b/tests/Doctrine/Tests/Models/VersionedOneToMany/Article.php @@ -0,0 +1,45 @@ +tags = new ArrayCollection(); + } +} diff --git a/tests/Doctrine/Tests/Models/VersionedOneToMany/Category.php b/tests/Doctrine/Tests/Models/VersionedOneToMany/Category.php new file mode 100644 index 00000000000..d4dbdefbba5 --- /dev/null +++ b/tests/Doctrine/Tests/Models/VersionedOneToMany/Category.php @@ -0,0 +1,45 @@ +articles = new ArrayCollection(); + } +} diff --git a/tests/Doctrine/Tests/ORM/Functional/MergeVersionedOneToManyTest.php b/tests/Doctrine/Tests/ORM/Functional/MergeVersionedOneToManyTest.php new file mode 100644 index 00000000000..b51a24013c1 --- /dev/null +++ b/tests/Doctrine/Tests/ORM/Functional/MergeVersionedOneToManyTest.php @@ -0,0 +1,55 @@ +_schemaTool->createSchema( + [ + $this->_em->getClassMetadata('Doctrine\Tests\Models\VersionedOneToMany\Category'), + $this->_em->getClassMetadata('Doctrine\Tests\Models\VersionedOneToMany\Article'), + ] + ); + } catch (ORMException $e) { + } + } + + /** + * This test case asserts that a detached and unmodified entity could be merge without firing + * OptimisticLockException. + */ + public function testSetVersionOnCreate() + { + $category = new Category(); + $category->name = 'Category'; + + $article = new Article(); + $article->name = 'Article'; + $article->category = $category; + + $this->_em->persist($article); + $this->_em->flush(); + $this->_em->clear(); + + $articleMerged = $this->_em->merge($article); + + $articleMerged->name = 'Article Merged'; + + $this->_em->flush(); + $this->assertEquals(2, $articleMerged->version); + } +}