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.