Details
-
Type:
Bug
-
Status:
Closed
-
Priority:
Major
-
Resolution: Fixed
-
Affects Version/s: 1.1.4
-
Fix Version/s: 1.2.0-BETA1
-
Component/s: Record
-
Labels:None
Description
This issue is continuation of issue #2488 from Trac. I have prepared Test case showing that the problem is seriously. Below original content.
A record gets STATE_PROXY state at hydration when its properties are not fully loaded. Here is a condition (placed in Doctrine_Record::hydrate()):
if ( ! $this->isModified() && count($this->_values) < $this->_table->getColumnCount()) { $this->_state = self::STATE_PROXY; }
But at first setting a column value (whatever if the column value was loaded or not), the record gets STATE_DIRTY and "forgets" its proxy state.
In effect a call to any not loaded column of the record causes returning null value. It should, of course, load remaining column values and change record state from STATE_PROXY to STATE_DIRTY. It doesn't load because current record state is already STATE_DIRTY.
I'm attaching a patch, which fixes Doctrine_Record::load() in the described situation.
In my opinion usage of STATE_PROXY must be rethinked. STATE_PROXY can mean:
1. STATE_CLEAN + not fully loaded columns (proxy)
2. STATE_DIRTY + not fully loaded columns (proxy)
Currently it only points the first situation so there is not way to identify the second situation (and it is silently ignored).
I'm including a patch.
I think that the patch needs a little explanation. To solve the problem I see 2 solutions:
1. create new state, eg. STATE_PROXY_MODIFIED being activated when a proxy record gets modified
2. transform existing conditions to check proxy state dynamically using new Doctrine_Record::isInProxyState() method
I chosen the second as a less invasive way. A record is in proxy state when it has any not loaded properties - this must be found out by the method. But... currently there is no way to find this. Doctrine_Null object in $record->_data means that property is not loaded yet OR it has null value.
In the patch I divided real null value (simply stored as null in _data) from unknown (not loaded) value (stored as Doctrine_Null).