Details

    • Type: Sub-task Sub-task
    • Status: Resolved
    • Priority: Minor Minor
    • Resolution: Fixed
    • Affects Version/s: None
    • Fix Version/s: 2.1
    • Component/s: ORM
    • Security Level: All
    • Labels:
      None

      Description

      Currently the only way to force an uninitialized collection to load itself is to call one of its methods (e.g. ->count()).

      Roman suggested something like $em->initialize($collection)

        Issue Links

          Activity

          Dave Keen created issue -
          Hide
          Jonathan H. Wage added a comment -

          Why not just make the initialize method public on PersistentCollection:

          $collection->initialize();
          

          ??

          Show
          Jonathan H. Wage added a comment - Why not just make the initialize method public on PersistentCollection: $collection->initialize(); ??
          Hide
          Roman S. Borschel added a comment -

          Even if that is done, userland code should not use the PersistentCollection API. Remember that a PersistentCollection is supposed to be a transparent wrapper around a Collection implementation. If a user calls $coll->initialize() this code implicitly assumes the concrete type of the collection to be PersistentCollection, which is not a good idea. Userland code should always program to the Collection interface.

          Show
          Roman S. Borschel added a comment - Even if that is done, userland code should not use the PersistentCollection API. Remember that a PersistentCollection is supposed to be a transparent wrapper around a Collection implementation. If a user calls $coll->initialize() this code implicitly assumes the concrete type of the collection to be PersistentCollection, which is not a good idea. Userland code should always program to the Collection interface.
          Hide
          Roman S. Borschel added a comment -

          Such an initialize method should furthermore handle uninitialized proxies as well as uninitialized collections.

          Show
          Roman S. Borschel added a comment - Such an initialize method should furthermore handle uninitialized proxies as well as uninitialized collections.
          Hide
          Dave Keen added a comment -

          For extra points it might be nice if there was an extra cascade option for initialize, and possibly an event hook for pre and post initialize.

          Show
          Dave Keen added a comment - For extra points it might be nice if there was an extra cascade option for initialize, and possibly an event hook for pre and post initialize.
          Roman S. Borschel made changes -
          Field Original Value New Value
          Fix Version/s 2.1 [ 10022 ]
          Benjamin Eberlei made changes -
          Parent DDC-952 [ 12257 ]
          Issue Type New Feature [ 2 ] Sub-task [ 5 ]
          Benjamin Eberlei made changes -
          Assignee Roman S. Borschel [ romanb ] Benjamin Eberlei [ beberlei ]
          Hide
          Eric Muyser added a comment - - edited

          I just ran into a bug with this, I believe. I have a Blog which cascade deletes it's Feeds. In cascadeDetach it's saying the count($relatedEntities) is zero for Feeds after the call to unwrap(), even though I know it to be, say, 1 or 2 (output before detaching owner entity). However, if I do ->count() or count($relatedEntities) BEFORE unwrap(), then PersistentCollection by consequence is initialized, and it cascade deletes correctly. If it don't, it actually says the Feeds are still MANAGED after having detached the owner entity. So, yeah, this or some other form of auto-initialization would be useful.

          Note: In Blog, I have DQL which fetches Feeds JOINed to Blog, which may be causing the uninitialization (not sure). I'm using EXTRA LAZY LOADING.

          Show
          Eric Muyser added a comment - - edited I just ran into a bug with this, I believe. I have a Blog which cascade deletes it's Feeds. In cascadeDetach it's saying the count($relatedEntities) is zero for Feeds after the call to unwrap(), even though I know it to be, say, 1 or 2 (output before detaching owner entity). However, if I do ->count() or count($relatedEntities) BEFORE unwrap(), then PersistentCollection by consequence is initialized, and it cascade deletes correctly. If it don't, it actually says the Feeds are still MANAGED after having detached the owner entity. So, yeah, this or some other form of auto-initialization would be useful. Note: In Blog, I have DQL which fetches Feeds JOINed to Blog, which may be causing the uninitialization (not sure). I'm using EXTRA LAZY LOADING.
          Hide
          James Harvey added a comment - - edited

          I have also run into a problem with this: when adding a single entity to an empty collection and then calling flush(), the collection which should now have 1 entity in it actually has 2. I discovered that this can be fixed by calling count() on the collection prior to the flush() operation. I looked into the code and noticed that most methods in PersistentCollection.php (v2.0.3) call $this->initialize() as their first step, but the add() function did not. I think this may be an oversight? By adding $this->initialize() to the add() function my problem was resolved.

          Show
          James Harvey added a comment - - edited I have also run into a problem with this: when adding a single entity to an empty collection and then calling flush(), the collection which should now have 1 entity in it actually has 2. I discovered that this can be fixed by calling count() on the collection prior to the flush() operation. I looked into the code and noticed that most methods in PersistentCollection.php (v2.0.3) call $this->initialize() as their first step, but the add() function did not. I think this may be an oversight? By adding $this->initialize() to the add() function my problem was resolved.
          Hide
          Benjamin Eberlei added a comment -

          Hello James, not calling initialize() is a very important performance optimization. Consider your collection containing hundrets, thousands or more entities. You dont want to load them all into memory just to add one new entity.

          To solve your problem there is Collection::contains($entity) which will handle your collection correctly. in combination with "EXTRA_LAZY" support introduced in 2.1-DEV this is even very efficient.

          Show
          Benjamin Eberlei added a comment - Hello James, not calling initialize() is a very important performance optimization. Consider your collection containing hundrets, thousands or more entities. You dont want to load them all into memory just to add one new entity. To solve your problem there is Collection::contains($entity) which will handle your collection correctly. in combination with "EXTRA_LAZY" support introduced in 2.1-DEV this is even very efficient.
          Benjamin Eberlei made changes -
          Link This issue is required for DDC-1193 [ DDC-1193 ]
          Hide
          Benjamin Eberlei added a comment -

          Implemented $em->getUnitOfWork()->initializeObject().

          For this the proxy method __load() was turned from private to public and marked as /** @private */

          Show
          Benjamin Eberlei added a comment - Implemented $em->getUnitOfWork()->initializeObject(). For this the proxy method __load() was turned from private to public and marked as /** @private */
          Benjamin Eberlei made changes -
          Status Open [ 1 ] Resolved [ 5 ]
          Resolution Fixed [ 1 ]
          Benjamin Eberlei made changes -
          Workflow jira [ 11731 ] jira-feedback [ 14527 ]
          Benjamin Eberlei made changes -
          Workflow jira-feedback [ 14527 ] jira-feedback2 [ 16391 ]
          Benjamin Eberlei made changes -
          Workflow jira-feedback2 [ 16391 ] jira-feedback3 [ 18644 ]

          This list may be incomplete, as errors occurred whilst retrieving source from linked applications:

          • Request to http://www.doctrine-project.org/fisheye/ failed: Error in remote call to 'FishEye 0 (http://www.doctrine-project.org/fisheye/)' (http://www.doctrine-project.org/fisheye) [AbstractRestCommand{path='/rest-service-fe/search-v1/crossRepositoryQuery', params={query=DDC-733, expand=changesets[0:20].revisions[0:29],reviews}, methodType=GET}] : Received status code 503 (Service Temporarily Unavailable)

            People

            • Assignee:
              Benjamin Eberlei
              Reporter:
              Dave Keen
            • Votes:
              2 Vote for this issue
              Watchers:
              2 Start watching this issue

              Dates

              • Created:
                Updated:
                Resolved: