Bug #47975
initializeObject in a Entity is called at a time where no properties are loaded
Status: | Resolved | Start date: | 2013-05-06 | |
---|---|---|---|---|
Priority: | Must have | Due date: | ||
Assigned To: | Robert Lemke | % Done: | 0% |
|
Category: | Object | |||
Target version: | TYPO3 Flow Base Distribution - 2.0.1 | |||
PHP Version: | 5.4 | Complexity: | ||
Has patch: | No | Affected Flow version: | Git master |
Description
I have an Entity which is loaded during validation of a Action Argument. (The Action Argument is another Entity with relations to the Entity in question)
When initializeObject() is called all properties are missing and have not been loaded from persistence.
Here is the Backtrace:
https://gist.github.com/anonymous/5524256
Related issues
History
#1 Updated by Alexander Berl about 2 years ago
The real problem is, that the Doctrine Proxy __load() calls __wakeup() before the properties are actually loaded.
Here's a pseudo call stack for the class hierarchy of the proxies to original class, when the doctrine proxy is the entry point:
Class hierarchy: Doctrine Proxy (DP) > Flow Proxy (FP) > Original Class (OC) Call stack1: Doctrine Proxy gets loaded due to property access or via the GenericObjectValidator DP->__load() DP->__wakeup() DP->__load() FP->__wakeup() OC->__wakeup() DP->initializeObject(2) DP->__load() OC->initializeObject() DP->_entityPersister->load($this->_identifier, $this) Call stack2: Doctrine Proxy gets unserialized (e.g. unserialize('O:...') hacks used both in Flow and Doctrine) DP->__wakeup() DP->__load() [I think this is not really executed, since $this->_entityPersister would be empty in an empty unserialization] FP->__wakeup() OC->__wakeup() DP->initializeObject(2) DP->__load() OC->initializeObject()
Indentation refers to the call nesting level. As you can see, in both cases the initializeObject method gets called before the object properties are loaded. However, I'm not sure how to best deal with the premature
__wakeup()
in __load()
and preventing empty unserialization wakeups from triggering initializeObject.
A possible check could be that if __isInitialized__
is set and true and __entityPersister
is set, or if __isInitialized__
is set and false then skip the initializeObject invokation in the FlowProxy. You'd completely loose the initializeObject call in those cases though and at least in the first this is not desired I guess.
#2 Updated by rottenrice no-lastname-given about 2 years ago
I have the same problem but my call stack differs from your call stack.
My two Entities:
/** @Flow\Entity */ class Foo { public function __construct() { echo '__construct()'; } public function initializeObject($arg) { echo 'initializeObject('.$arg.')'; } public function injectSettings() { echo 'injectSettings()'; } } /** @Flow\Entity */ class Bar extends Foo { public function __construct() { echo '__construct()'; parent::__construct(); } }
Example code:
$bar = new Bar();
Output:
__construct() __construct() initializeObject(1) injectSettings() initializeObject(1)
Reason:
__construct() of Flow-Proxy (Foo)
[...] if ('Foo' === get_class($this)) { $this->Flow_Proxy_injectProperties(); } $this->initializeObject(1);
The injectProperties() in not executed but the initializeObject() is executed :/
#3 Updated by Adrian Föder about 2 years ago
I also had that; and I realized it's because of this gem here:
\Doctrine\ORM\Mapping\ClassMetadataInfo::newInstance
1 public function newInstance()
2 {
3 if ($this->_prototype === null) {
4 $this->_prototype = unserialize(sprintf('O:%d:"%s":0:{}', strlen($this->name), $this->name));
5 }
6
7 return clone $this->_prototype;
8 }
This is a dummy way to get an object without the constructor being called; but unfortunately this calls __wakeup and hence initializeObject(), of course without any properties then.
At the end, I had initializeObject() being called twice, once in that erroneous case and once when it's actually intended.
#4 Updated by Robert Lemke about 2 years ago
- Status changed from New to Accepted
Needs to be verified and solved for 2.0
#5 Updated by Karsten Dambekalns almost 2 years ago
- Target version changed from 2.0 to 2.0.1
#6 Updated by Robert Lemke almost 2 years ago
- Category changed from Persistence to Object
- Assigned To set to Robert Lemke
- PHP Version set to 5.4
#7 Updated by Robert Lemke almost 2 years ago
I think that this is a duplicate of #43659
#8 Updated by Robert Lemke almost 2 years ago
- Status changed from Accepted to Closed
Let's see if the fix for #43659 helps
#9 Updated by Andreas Förthner almost 2 years ago
- Status changed from Closed to New
The problem still exists, opening the issue again...
#10 Updated by Robert Lemke about 1 year ago
- Status changed from New to Resolved
Applied in changeset 6d2ea6b3fc5db90f3c7e6ccd0dea5304ec32ef5e.