[DDC-2036] indexBy breaks cascade remove Created: 20/Sep/12  Updated: 03/Oct/12  Resolved: 03/Oct/12

Status: Closed
Project: Doctrine 2 - ORM
Component/s: ORM
Affects Version/s: 2.3
Fix Version/s: None

Type: Bug Priority: Critical
Reporter: James Bench Assignee: Fabio B. Silva
Resolution: Can't Fix Votes: 0
Labels: None
Environment:

Ubuntu 12.04, PHP 5.3, 64 Bit, Symfony 2


Attachments: File AbstractData.php     File DDC2036Test.php     File Location.php     File LocationData.php     Text File msql.log     Text File sql_flush.log    

 Description   

Adding the annotation indexBy causes the cascade annotation to be ignored:

/**
*

  • @var ArrayCollection
  • @ORM\OneToMany(targetEntity="LocationData", mappedBy="location", indexBy="name", cascade= {"persist", "remove"}

    )
    */
    protected $data;

Will cause an error when deleting the objects:

An exception occurred while executing 'DELETE FROM location WHERE id = ?' with params

{"1":19306}

:

SQLSTATE[23000]: Integrity constraint violation: 1451 Cannot delete or update a parent row: a foreign key constraint fails (`symfony`.`location_data`, CONSTRAINT `FK_2DF7462364D218E` FOREIGN KEY (`location_id`) REFERENCES `location` (`id`))

Removing indexBy fixes the issue.

My class structure is:

Location has many LocationData
LocationData extends AbstractData

The name field I am trying to index by comes from the AbstractData class.



 Comments   
Comment by Fabio B. Silva [ 23/Sep/12 ]

Hi James

Do you have a failing test case ?
Could you attach/paste your entity please ?

Thanks

Comment by James Bench [ 28/Sep/12 ]

Entity exhibiting the behavior.

Comment by Fabio B. Silva [ 29/Sep/12 ]

Hi James,
I can't reproduce,

Are you sure that you dont have more than one LocationData whith the same name ?

When working with indexBy the index columns must be unique into the collection.
I recommend that you add a unique constrain in the columns name.

If i'm wrong about it, please
Could you change the added test case and try to make it fails ?

Thanks

Comment by James Bench [ 02/Oct/12 ]

Hi Fabio,

The test case uses a SQLite DB without any foreign keys so the issue wouldn't be apparent.

How would I run the test against a MySQL db?

I've also attached the SQL log for the script I'm running, it looks the same as the output from the testcase.

Cheers,JB

Comment by James Bench [ 02/Oct/12 ]

SQL Log from script causing errors.

Comment by Fabio B. Silva [ 02/Oct/12 ]

Hi James,

You must copy phpunit.xml.dist to phpunit.xml and change the database configurations.

I have attached the mysql log, the test case works fine.

Comment by James Bench [ 02/Oct/12 ]

It appears that it only attempts to delete 68 LocationData rows but in the database there are 76.

Comment by James Bench [ 02/Oct/12 ]

Okay, I've found the reason for this; the name isn't unique, some are duplicated.
Once the duplicates are removed there are 68 rows.
I'll add a unique index to the name column and hopefully this problem will go away.

Not sure whether you would consider this a bug.

Thanks for your help.

Comment by Fabio B. Silva [ 02/Oct/12 ]

No problem, you are welcome

Actually isn't a bug, it is a documented behavior.

"Fields that are used for the index by feature HAVE to be unique in the database."

http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/tutorials/working-with-indexed-associations.html#working-with-indexed-assocations

Comment by Fabio B. Silva [ 03/Oct/12 ]

Fields that are used for the index by feature HAVE to be unique in the database.

http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/tutorials/working-with-indexed-associations.html#working-with-indexed-assocations

Generated at Sat Nov 22 03:06:23 UTC 2014 using JIRA 6.2.3#6260-sha1:63ef1d6dac3f4f4d7db4c1effd405ba38ccdc558.