I have noticed a strange behaviour when intercepting the preUpdate row hook in Propel (1.6.1). Consider this schema:
<?xml version="1.0" encoding="UTF-8"?>
<database name="test" defaultIdMethod="native" baseClass="MyBaseObject">
<table name="test_event">
<column name="id" type="integer" required="true" primaryKey="true" autoIncrement="true" />
<column name="name" type="varchar" size="50" required="true" />
<column name="description" type="varchar" size="250" />
<column name="location" type="varchar" size="250" />
<column name="nearest_city" type="varchar" size="100" />
<column name="start_time" type="timestamp" />
<column name="duration_mins" type="integer" />
<column name="organiser_id" type="integer" required="true" />
<foreign-key foreignTable="test_organiser">
<reference local="organiser_id" foreign="id" />
</foreign-key>
</table>
<table name="test_organiser">
<column name="id" type="integer" required="true" primaryKey="true" autoIncrement="true" />
<column name="name" type="varchar" size="50" required="true" />
<column name="email" type="varchar" size="100" />
</table>
</database>
I've noticed that an update to TestOrganiser results in two preUpdate calls to the custom class - one for itself and one for TestEvent. However, if the first table is updated, only itself gets a preUpdate call. Why is this?
Edit: earlier I added my own answer. However if anyone would like to add further detail, please do - the more clarity the better! If an update is made to test_organiser
, in what sense can test_event
be said to be updating, especially since it is marked as unmodified?
I typed out most of this question, and then worked it out for myself! I thought I would add the q anyway, as I think it is of general interest.
I'd initially thought that TestEvent ought to get the two calls - one for itself, and one for its dependent object. But a save to TestEvent doesn't affect TestOrganiser, since the relation goes out from test_event to test_organiser.
So, the Propel behaviour is correct; since test_organiser is dependent on test_event, both are notified if the former is modified. This can be thought of like a non-hierarchical parent-child relation (test_event has the foreign key, so that is the 'parent').
My solution to filtering out related row notifications of this kind (and non-modified rows generally) is simply to do this in the custom row ancestor class:
public function preUpdate(PropelPDO $con = null)
{
// Ignore (related) rows with no changes
if (!$this->isModified())
{
return true;
}
// Rest of handling code here...
}