We are moving our forum in GitHub Discussions. For questions about Phalcon v3/v4 you can visit here and for Phalcon v5 here.

"Maximum recursion depth exceeded" when saving a related record

For the life of me, I can't figure this out. It looks like Phalcon goes into an infinite loop when saving related records. For the sake of simplicity, there are 2 classes - CustomerOrder and OrderedItem.

CustomerOrder initialize():
$this->hasMany('ID', '\order\OrderedItem', 'customerOrderID', array('alias' => 'OrderedItems'));

OrderedItem initialize():
$this->belongsTo('customerOrderID', 'order\CustomerOrder', 'ID', array('alias' => 'CustomerOrder'));

There are other relations too, but these do not seem to be affecting the issue, as everything works if I isolate out the above relation.

The code goes roughly like this:

$item = new OrderedItem();
$item->customerOrder = $order;

$order->orderedItems = array($item);

Behind the scenes it's hammering the database with 100 identical queries in a row:

UPDATE `CustomerOrder` SET ... WHERE `ID` = '54'

No before/afterSave functions are used, so that loop takes place inside Phalcon. The only way to make it work is to remove the relationship definition and work with ID's directly, but then what's the point of this...

Also here's the trace:

( ! ) Fatal error: Maximum recursion depth exceeded in /var/www/lc2/application/controller/OrderController.php on line 784
Call Stack
#   Time    Memory  Function    Location
1   0.0001  260656  {main}( )   ../index.php:0
2   0.0010  494968  Phalcon\Mvc\Application->handle( )  ../index.php:265
3   0.0101  1324496 OrderController->addToCartAction( ) ../index.php:0
4   0.0101  1325608 OrderController->addProductToCart( )    ../OrderController.php:558
5   0.3436  2933512 Phalcon\Mvc\Model->save( )  ../OrderController.php:784

I have upgraded to Phalcon 1.3.0 but the same issue was present in 1.2.6 as well.

This looks like it should work. The only thing I see is that your hasMany relationship model starts with a \, whereast the belongsTo doesn't. I can't imagine how that would cause this, but it's something.

You've said you simplified it down - which is a good idea for an initial post. Can you post more complete code? Maybe in the process of simplification you removed something causing the problem.

Looking at simplified code of my own post, I figured to take out the following lines and it works:

//$item->customerOrder = $order;

But still, why should that be causing any problems?

Yeah, I don't think it was meant to be used like that--although I don't think it should cause a problem either. What you are doing there also is shedding the implicit transaction you would get if you had not saved the item by iteself.

$order = new CustomerOrder();
/* Change some other order properties, do not save!*/

$items = array();

$item = new OrderedItem();
/* Change order items properties, do not save! */

$another_item = new OrderedItem();
/* Change order items properties, do not save! */

$order->orderedItems = $items;

if ($order->save()){  //now let's save
    //Implicit transaction, how cool!
    //all items will be saved--automatically related to the Order, and if anything fails it all fails
    //uhh...we rolled back..nothing was saved.  Better luck next time.