ZF-3144: Cascading db operations do not work when 'refColumns' is not explicity set inside $_referenceMap.

Issue Type: Bug Created: 2008-04-18T04:28:40.000+0000 Last Updated: 2012-05-28T21:13:10.000+0000 Status: Resolved Fix version(s): - 1.12.0 (27/Aug/12)

Reporter: Piotr Czachur (zimnyx) Assignee: Adam Lundrigan (adamlundrigan) Tags: - Zend_Db_Table

  • FixForZF1.12
  • state:patch-ready-for-review
  • zf-caretaker-adamlundrigan
  • zf-crteam-review

Related issues: Attachments: - ZF-3144_fix.patch


<pre class="highlight">
class Files extends Zend_Db_Table
    protected $_name = 'files';
    protected $_rowClass = 'File';
    protected $_referenceMap = array(
        'Email' => array(
            'columns'           => 'emailId',
            'refTableClass'     => 'Emails',
            // Without next row CASCADE doesn't work despite id is PK, and should be retrieved automaticaly
            // Manual says that if refColumns is not set it will be be discovered from table schema as PK
            'refColumns'        => 'id',
            'onDelete'          => self::CASCADE,

Btw I noticed, that without 'refColumns' set to 'id' CASCADE query looks like "DELETE FROM files WHERE phoneId = 0" - this is just wrong.


Posted by Wil Sinclair (wil) on 2008-04-18T13:20:28.000+0000

Please evaluate and categorize as necessary.

Posted by Wil Sinclair (wil) on 2008-12-04T13:17:29.000+0000

Reassigning to Ralph since he's the new maintainer of Zend_Db

Posted by Ralph Schindler (ralph) on 2009-01-10T11:58:12.000+0000

Will evaluate within 2 weeks

Posted by Piotr Czachur (zimnyx) on 2009-04-10T03:48:01.000+0000

Is this forgotten issue?

Posted by Ralph Schindler (ralph) on 2009-05-19T12:29:47.000+0000

can you describe the 2 tables and/or produce a small script (you can use sqlite ::memory:: to accomplish this) that will demonstrate the problem?

Posted by Piotr Czachur (zimnyx) on 2009-05-21T00:59:24.000+0000

Ralph, here you go:

<pre class="highlight">
CREATE TABLE `products` (
  `id` tinyint(4) NOT NULL auto_increment,
  PRIMARY KEY  (`id`)

CREATE TABLE `files` (
  `id` tinyint(4) NOT NULL auto_increment,
  `productId` tinyint(4) NOT NULL,
  PRIMARY KEY  (`id`)

INSERT INTO products values (1),(2);
INSERT INTO files values (7,2),(8,2);

<pre class="highlight">
class Default_Model_DbTable_Files extends Zend_Db_Table
    protected $_name = 'files';
    protected $_referenceMap = array(
        'Product' => array(
            'columns'           => 'productId',
            'refTableClass'     => 'Default_Model_DbTable_Products',
           // 'refColumns'        => 'id',    
            'onDelete'          => self::CASCADE,

class Default_Model_DbTable_Products extends Zend_Db_Table
    protected $_name = 'products';  
    protected $_dependentTables = array('Default_Model_DbTable_Files');


$productsTable = new Default_Model_DbTable_Products;

<pre class="highlight">
/trunk/lib/Zend/Db/Table/Abstract.php:1085 'Undefined index:  refColumns'
DELETE FROM `files` WHERE (`productId` = 0)
DELETE FROM `products` WHERE (`products`.`id` = 2)

Uncommenting // 'refColumns' => 'id', fixes problem.

Posted by Ralph Schindler (ralph) on 2011-02-17T15:03:19.000+0000

Is the suggestion here to throw an exception when refColumns is not present? Seems that should be the behavior because if you don't explicitly say what the reference column is, Zend_Db_Table shouldn't make an assumption about what it's related to (it could technically be another column, not the PK).

Posted by Piotr Czachur (zimnyx) on 2011-03-15T04:18:55.000+0000


I quit using ZF almost 2 years ago. Please decide on your own.

Posted by Bento Vilas Boas (bento.vilas.boas) on 2011-07-27T04:12:23.000+0000


According to official documentation, if refColumns is not present, pk will be used.…

This issue was fixed somewhere along the way.

Posted by Adam Lundrigan (adamlundrigan) on 2011-09-23T14:50:36.000+0000

Implemented Piotr's reproduction code as a unit test (patch attached). The result is still the same as he found:

<pre class="highlight">
2) Zend_Db_Table_Pdo_SqliteTest::testCascadingOperationReferenceColumnFallsBackToPrimaryKeyWhenNotSpecified
Undefined index: refColumns


Ralph has said that refColumns should be explicitly specified, and the current implementation doesn't try to "autodiscover" the reference columns. However, the ZF manual says the opposite. Should we change the implementation or the manual?

As this issue has been around since at least 1.5.1, anyone using cascading operations would already have specified their reference columns, so I would vote for updating the manual page to note that specifying 'refColumns' is required for cascade operations to work. I would also change the implementation to throw an exception if 'refColumns' is not specified.

Posted by Adam Lundrigan (adamlundrigan) on 2011-09-26T19:39:51.000+0000

After discussion with [~ralph] on IRC, it was decided that the manual should be updated to display a note saying that as of 1.11.11 the refColumns key is required, and an exception should be thrown if it is not present. Attached is a patch implementing these changes.


Posted by Adam Lundrigan (adamlundrigan) on 2012-05-11T01:09:01.000+0000

Reflecting on this, is throwing an exception the best course of action? With pre-1.12, any applications that use referenceMap without refColumns emit a notice and the cascade fails (see here above), but after this patch is applied it will throw an exception that will halt the entire application unless it's caught Would it be better to silently ignore the referenceMap entry if it doesn't have a refColumns key?

Posted by Rob Allen (rob) on 2012-05-28T19:36:30.000+0000

Updated manual to better reflect reality in svn r24820. Do not through an exception as this will cause a B/C break for no real benefit at this stage in ZF1's lifecycle.

Have you found an issue?

See the Overview section for more details.


© 2006-2018 by Zend, a Rogue Wave Company. Made with by awesome contributors.

This website is built using zend-expressive and it runs on PHP 7.