After going through ObjectHydrator.php line by line, I saw that you can 
force the hydrator to update the existing entity using a hint in the query 
object. So, to fix my problem, I edited the findWithPartialObservations 
method and added a single line:

$query->setHint(Query::HINT_REFRESH, true);

Now there's no need to run clear(), so I don't have to deal with the "new 
entity" error.


On Thursday, July 9, 2015 at 3:55:15 PM UTC-5, Danny Ferguson wrote:
>
> I'm running a complex DQL query that returns partial entities using 
> ResultSetMapping. Since the table has so many columns and I only need a 
> couple, I end up with entities that only have the needed properties 
> populated. The large table is an association of the entity I'm actually 
> fetching. I did this for performance reasons and it works very well when I 
> run it once. But, if I try to do this partial entity fetch more than once 
> during a request, then things get strange.
>
> $benchmarks = array('unemployment_rate', 'graduation_rate');
> $subs = $subscriptionModel->findWithPartialObservations($study, $year, 
> $benchmarks);
>
> foreach ($subs as $sub) {
>     // This is only a partial observation, by design...
>     $observation = $sub->getObservation();
>
>     // This value will be populated
>     $value = $observation->get('unemployment_rate');
>
>     // If I try to get some other property, it will return null. That's 
> ok.
>     $isNull = $observation->get('some_other_property');
> }
>
>
> // So far, so good. But if I run this again on the same request, with 
> different benchmarks, the problems start:
> $benchmarks = array('cost_per_credit_hour', 'abc_grades');
> $subs = $subscriptionModel->findWithPartialObservations($study, $year, 
> $benchmarks);
>
> foreach ($subs as $sub) {
>     // This appears to be the same partial observation I got above, but I 
> don't want that.
>     $observation = $sub->getObservation();
>
>     // This value is missing
>     $value = $observation->get('cost_per_credit_hour');
>
>     // getObservation() appears to be returning the same observation as 
> the first time through, 
>     // with the wrong properties populated
> }
>
> So, I need to force each findWithPartialObservations() call to go back to 
> the database so that when I call getObservation() on one of the results, 
> the correct properties are populated. After some reading, I decided that 
> calling clear() on the entity manager might be the answer. That tells it to 
> forget all entities and go back to the database when the fetch is run, 
> right? Well, I added the clear between the two fetches above (in other 
> words, right above the "So far, so good" comment. But when I run this I get 
> errors like: 
>
> A new entity was found through the relationship 
>> 'Mrss\Entity\Subscription#observation' that was not configured to cascade 
>> persist operations for entity: Observation id: 1693. To solve this issue: 
>> Either explicitly call EntityManager#persist() on this unknown entity or 
>> configure cascade persist  this association in the mapping for example 
>> @ManyToOne(..,cascade={"persist"}).
>>
>
> Now, I don't want the observation to persist on cascade because the 
> observation is only partially populated. That would erase data by 
> overwriting good values with nulls for the fields that weren't populated. 
> I've tried passing entity names to clear() to make it more limited, but I 
> always get some variation on that error message. Can anyone guide me 
> towards a way to force my complex fetch to be drawn from the database 
> rather than the unit of work? 
>

-- 
You received this message because you are subscribed to the Google Groups 
"doctrine-user" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To post to this group, send email to [email protected].
Visit this group at http://groups.google.com/group/doctrine-user.
For more options, visit https://groups.google.com/d/optout.

Reply via email to