Details
-
Type:
Bug
-
Status:
Resolved
-
Priority:
Blocker
-
Resolution: Won't Fix
-
Affects Version/s: 1.1.4
-
Fix Version/s: 1.2.0-ALPHA1
-
Component/s: Query
-
Labels:None
Description
moving from trac, issue #2410 by zyxist
This ticket is related to the MySQL database and InnoDB engine with exporting all the information about the models (including foreign keys).
I have two tables connected with one-to-many relationship. First, I select a row from a "master" table with attached a field from the related "servant" row:
$master = Doctrine_Query::create()
->select('m.*, s.bar AS joe')
->from('Ticket_9999_Master m')
->innerJoin('m.Ticket_9999_Servant s')
->where('m.id = 1')
->fetchOne();
Next, I modify one of the columns in the master row and save everything:
$master->foo = 5; $master->save();
Expected result: the master row is updated.
Actual result: MySQL error:
Integrity constraint violation: 1452 Cannot add or update a child row: a foreign key constraint fails (`doctrine`.`ticket_9999_master`, CONSTRAINT `ticket_9999_master_servant_id_ticket_9999_servant_id` FOREIGN KEY (`servant_id`) REFERENCES `ticket_9999_servant` (`id`))
If we remove "AS joe" part from the query, it gives the correct result. I noticed that with this alias, Doctrine forgets to retrieve the primary key of the servant row and this produces an invalid UPDATE query. There are two possible ways to retrieve this:
1. Use the data from the "Master" row, as we fetch everything, including the ID of the servant row. Doctrine knows about the relationship and potentially can use it.
2. Simply select the servant id automatically with the "s.bar" column.
Tested on software:
PHP 5.2.10, PHP 5.3.0
MySQL 5.1.36
Doctrine 1.1-DEV (rev. 6217)
Two words from me:
Well, the problem is not the saving process but the thing that selecting a relation only with aliased field does not retrieve the ID. I mean that this query:
SELECT m.*, s.bar FROM Master m, m.Servant S
is also selecting s.id field, because Doctrine always needs it, right? Adding an alias "s.bar AS something" makes the query not select "s.id", so in save() Doctrine thinks Servant is a new record. And that's why mysql throws "Integrity constraint violation".