Several features to batch eager selects more efficently (DDC-952)

[DDC-733] Implement a way of forcing a PersistentCollection to initialize itself Created: 06/Aug/10  Updated: 05/Jun/11  Resolved: 05/Jun/11

Status: Resolved
Project: Doctrine 2 - ORM
Component/s: ORM
Affects Version/s: None
Fix Version/s: 2.1
Security Level: All

Type: Sub-task Priority: Minor
Reporter: Dave Keen Assignee: Benjamin Eberlei
Resolution: Fixed Votes: 2
Labels: None

Issue Links:
Dependency
is required for DDC-1193 cascadeRemove misses associations due... Resolved

 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)



 Comments   
Comment by Jonathan H. Wage [ 07/Aug/10 ]

Why not just make the initialize method public on PersistentCollection:

$collection->initialize();

??

Comment by Roman S. Borschel [ 07/Aug/10 ]

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.

Comment by Roman S. Borschel [ 07/Aug/10 ]

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

Comment by Dave Keen [ 07/Aug/10 ]

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.

Comment by Eric Muyser [ 14/Mar/11 ]

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.

Comment by James Harvey [ 20/Mar/11 ]

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.

Comment by Benjamin Eberlei [ 29/Mar/11 ]

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.

Comment by Benjamin Eberlei [ 05/Jun/11 ]

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

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

Generated at Thu Dec 18 07:19:11 UTC 2014 using JIRA 6.2.3#6260-sha1:63ef1d6dac3f4f4d7db4c1effd405ba38ccdc558.