@@ -2332,7 +2332,6 @@ function ($assoc) { return $assoc['isCascadeMerge']; }
23322332 *
23332333 * @param object $document
23342334 * @param array $visited
2335- * @param array $insertNow
23362335 */
23372336 private function cascadePersist ($ document , array &$ visited )
23382337 {
@@ -2348,14 +2347,35 @@ function ($assoc) { return $assoc['isCascadePersist']; }
23482347
23492348 if ($ relatedDocuments instanceof Collection || is_array ($ relatedDocuments )) {
23502349 if ($ relatedDocuments instanceof PersistentCollection) {
2350+ if ($ relatedDocuments ->getOwner () !== $ document ) {
2351+ $ relatedDocuments = $ this ->fixPersistentCollectionOwnership ($ relatedDocuments , $ document , $ class , $ mapping ['name ' ]);
2352+ }
23512353 // Unwrap so that foreach() does not initialize
23522354 $ relatedDocuments = $ relatedDocuments ->unwrap ();
23532355 }
23542356
2355- foreach ($ relatedDocuments as $ relatedDocument ) {
2357+ $ count = 0 ;
2358+ foreach ($ relatedDocuments as $ relatedKey => $ relatedDocument ) {
2359+ if ( ! empty ($ mapping ['embedded ' ])) {
2360+ list (, $ knownParent , ) = $ this ->getParentAssociation ($ relatedDocument );
2361+ if ($ knownParent && $ knownParent !== $ document ) {
2362+ $ relatedDocument = clone $ relatedDocument ;
2363+ $ relatedDocuments [$ relatedKey ] = $ relatedDocument ;
2364+ }
2365+ $ pathKey = ! isset ($ mapping ['strategy ' ]) || CollectionHelper::isList ($ mapping ['strategy ' ]) ? $ count ++ : $ relatedKey ;
2366+ $ this ->setParentAssociation ($ relatedDocument , $ mapping , $ document , $ mapping ['name ' ] . '. ' . $ pathKey );
2367+ }
23562368 $ this ->doPersist ($ relatedDocument , $ visited );
23572369 }
23582370 } elseif ($ relatedDocuments !== null ) {
2371+ if ( ! empty ($ mapping ['embedded ' ])) {
2372+ list (, $ knownParent , ) = $ this ->getParentAssociation ($ relatedDocuments );
2373+ if ($ knownParent && $ knownParent !== $ document ) {
2374+ $ relatedDocuments = clone $ relatedDocuments ;
2375+ $ class ->setFieldValue ($ document , $ mapping ['name ' ], $ relatedDocuments );
2376+ }
2377+ $ this ->setParentAssociation ($ relatedDocuments , $ mapping , $ document , $ mapping ['name ' ]);
2378+ }
23592379 $ this ->doPersist ($ relatedDocuments , $ visited );
23602380 }
23612381 }
@@ -2507,7 +2527,20 @@ public function unscheduleOrphanRemoval($document)
25072527 }
25082528 }
25092529
2510- private function fixPersistentCollectionOwnership (PersistentCollection $ coll , $ document , $ class , $ propName )
2530+ /**
2531+ * Fixes PersistentCollection state if it wasn't used exactly as we had in mind:
2532+ * 1) sets owner if it was cloned
2533+ * 2) clones collection, sets owner, updates document's property and, if necessary, updates originalData
2534+ * 3) NOP if state is OK
2535+ * Returned collection should be used from now on (only important with 2nd point)
2536+ *
2537+ * @param PersistentCollection $coll
2538+ * @param object $document
2539+ * @param ClassMetadata $class
2540+ * @param string $propName
2541+ * @return PersistentCollection
2542+ */
2543+ private function fixPersistentCollectionOwnership (PersistentCollection $ coll , $ document , ClassMetadata $ class , $ propName )
25112544 {
25122545 $ owner = $ coll ->getOwner ();
25132546 if ($ owner === null ) { // cloned
@@ -2519,8 +2552,10 @@ private function fixPersistentCollectionOwnership(PersistentCollection $coll, $d
25192552 $ newValue = clone $ coll ;
25202553 $ newValue ->setOwner ($ document , $ class ->fieldMappings [$ propName ]);
25212554 $ class ->reflFields [$ propName ]->setValue ($ document , $ newValue );
2522- // @todo following line should be superfluous once collections are stored in change sets
2523- $ this ->setOriginalDocumentProperty (spl_object_hash ($ document ), $ propName , $ newValue );
2555+ if ($ this ->isScheduledForUpdate ($ document )) {
2556+ // @todo following line should be superfluous once collections are stored in change sets
2557+ $ this ->setOriginalDocumentProperty (spl_object_hash ($ document ), $ propName , $ newValue );
2558+ }
25242559 return $ newValue ;
25252560 }
25262561 return $ coll ;
0 commit comments