| Q | A
|------------ | ------
| BC Break | no
| Version | 2.0.5
We are having same (or similar) issue described in this issue and PR on ORM albeit with Mongo ODM although the doctrine/persistence is on 1.3.6.
Aside from embedded documents, we get the Error: Typed property Document::$field must not be accessed before initialization. error for scalar types, probably for all fields actually.
Change \Doctrine\ODM\MongoDB\Mapping\ClassMetadata::getIdentifierValue() into:
public function getIdentifierValue(object $document)
{
return $this->reflFields[$this->identifier]->isInitialized($document) ? $this->reflFields[$this->identifier]->getValue($document) : null;
}
@tehplague @josefsabl if one of you have a moment please open a PR with test case, that'd be much appreciated!
This happens on postgres too, so it's probably another problem.
This happens on postgres too, so it's probably another problem.
@MLDMoritz how this happening on Postgres is relevant for ODM and MongoDB?
There is probably a more underlying issue, as this seems to happen on odm and orm.
@MLDMoritz If you compare my snippet from above with the current body of said function you will see what kind of an issue there is. Both ODM and ORM implement the same ClassMetadata interface and both implementations need to be changed to account for typed properties.
To everybody reporting: could you please test and see if #2188 fixes the issues for you?
Unfortunatelly no, I was able to reproduce the problem in v2.1.2. As I tried to reproduce and isolate, it went away.
I am not sure if it helps, but this is the code I put to base documents so as to help debugging them (all the doctrine stuff crashes var_dump on memory).
public function __debugInfo()
{
try {
return array_reduce(
array_filter(
(new \ReflectionClass($this))
->getProperties(\ReflectionProperty::IS_PUBLIC),
fn(
\ReflectionProperty $property
): bool => !\Nette\Utils\Strings::startsWith(
'Proxy\__PM__\\',
$property->getDeclaringClass()->getNamespaceName(),
)
),
fn(
array $carry,
\ReflectionProperty $property
): array => array_merge(
$carry,
[$property->getName() => $this->{$property->getName()}]
),
[]
);
} catch (\ReflectionException $e) {
throw new \LogicException(
$e->getMessage(),
$e->getCode(),
$e
);
}
}
When I tried to debug the document like: var_dump($document) I got the aforementioned error. The document has referenced document Foo which property $bar IS in the database yet the PHP complained that it is uninitialized.
I changed the code to: echo $document->foo->bar; var_dump($document); which for sure displayed the content of $bar and the var_dump also passed and displayed correct data.
After I removed the echo, it still works 馃.
@josefsabl it seems to me that you are the one accessing uninitialized properties in [$property->getName() => $this->{$property->getName()}] part. You need to account for uninitialized properties on your own since you're the one using reflection
Thanks for the reply. I don't understand this, however.
How is:
$this->foo
different from
$name = 'foo';
$this->{$name};
?
And what does it have to do with the Reflection?
The part that makes this a problem is that the property is not initialized not how do I access it. Or am I mislead?
Thanks again.
Hard to say what I was thinking 2 weeks ago, I must have mistakenly think you are accessing object's value with reflection, not via de facto $this->$name. I have never used documents with public properties so this is a bit of gray area for me, maybe new proxying can't handle it properly (although I expect it should). I believe that without an isolated test case we won't be able to help any further
I believe that without an isolated test case we won't be able to help any further
Yeah, I understand. The problem is, when I try to isolate it it always disappears and even if I put the code right back to the state where it was failing, it doesn't reappear. Weird stuff indeed :-)
@josefsabl maybe you're using cache that is not cleared properly?
@josefsabl maybe you're using cache that is not cleared properly?
馃Interesting idea. We have a custom made adapter that integrates Nette/Cache as Doctrine/Cache, although we use it in production for years there might be a bug. It is pretty simple thing however. But thanks for direction.
@josefsabl What I meant is Doctrine creates proxy classes on it's own and usually on production regeneration of those is disabled for performance (as you probably know). Considering that "the problem went away" as soon as you started working with the files is a sign for me of a cache that's stale.
This "bug" appeared for me in the localhost development environment with proxy cache set to AUTOGENERATE_EVAL.
Most helpful comment
@MLDMoritz If you compare my snippet from above with the current body of said function you will see what kind of an issue there is. Both ODM and ORM implement the same
ClassMetadatainterface and both implementations need to be changed to account for typed properties.