Details
Description
class User extends Doctrine_Record { public function setTableDefinition() { $this->hasColumn('username', 'string', 64, array('notnull' => true)); $this->hasColumn('password', 'string', 128, array('notnull' => true)); } public function setUp() { $this->hasMany('Role as Roles', array('local' => 'id_user', 'foreign' => 'id_role', 'refClass' => 'UserRole')); $this->actAs('SoftDelete'); } } class Role extends Doctrine_Record { public function setTableDefinition() { $this->hasColumn('name', 'string', 64); } public function setUp() { $this->hasMany('User as Users', array('local' => 'id_role', 'foreign' => 'id_user', 'refClass' => 'UserRole')); } } class UserRole extends Doctrine_Record { public function setTableDefinition() { $this->hasColumn('id_user', 'integer', null, array('primary' => true)); $this->hasColumn('id_role', 'integer', null, array('primary' => true)); } public function setUp() { $this->hasOne('User', array('local' => 'id_user', 'foreign' => 'id', 'onDelete' => 'CASCADE')); $this->hasOne('Role', array('local' => 'id_role', 'foreign' => 'id', 'onDelete' => 'CASCADE')); } } $role = new Role(); $role->name = 'publisher'; $role->save(); $role = new Role(); $role->name = 'reviewer'; $role->save(); $role = new Role(); $role->name = 'mod'; $role->save(); $user = new User(); $user->fromArray(array( 'username' => 'test', 'password' => 'test', 'Roles' => array(1, 2, 3), )); $user->save(); //--------------------- here goes the failure $user->fromArray(array( 'Roles' => array(1, 3), )); $user->save();
After a User is saved once with some roles, it cannot be saved here with another combination of roles, consisting of some roles which was saved to the User before.
In short, ->unlink() in fromArray method does not schedule a deletion of old relations before adding new ones on save, like it was in previous versions of Doctrine.
Hence the primary key constraint is violated and the exception is thrown:
SQLSTATE[23000]: Integrity constraint violation: 1062 Duplicate entry '2-1' for key 1
#0 D:\projekty\cms-trunk\cms\library\Doctrine\Doctrine\Connection\Statement.php(269): Doctrine_Connection->rethrowException(Object(PDOException), Object(Doctrine_Connection_Statement))
#1 (...)\library\Doctrine\Doctrine\Connection.php(1032): Doctrine_Connection_Statement->execute(Array)
#2 (...)\library\Doctrine\Doctrine\Connection.php(677): Doctrine_Connection->exec('INSERT INTO `us...', Array)
#3 (...)\library\Doctrine\Doctrine\Connection\UnitOfWork.php(631): Doctrine_Connection->insert(Object(Doctrine_Table), Array)
#4 (...)\library\Doctrine\Doctrine\Connection\UnitOfWork.php(562): Doctrine_Connection_UnitOfWork->processSingleInsert(Object(UserRole))
#5 (...)\library\Doctrine\Doctrine\Connection\UnitOfWork.php(81): Doctrine_Connection_UnitOfWork->insert(Object(UserRole))
#6 (...)\library\Doctrine\Doctrine\Connection\UnitOfWork.php(452): Doctrine_Connection_UnitOfWork->saveGraph(Object(UserRole))
#7 (...)\library\Doctrine\Doctrine\Connection\UnitOfWork.php(137): Doctrine_Connection_UnitOfWork->saveAssociations(Object(User))
#8 (...)\library\Doctrine\Doctrine\Record.php(1690): Doctrine_Connection_UnitOfWork->saveGraph(Object(User))
#9 (...)\test3.php(124): Doctrine_Record->save()
#10
Now I see I duplicated the following ticket:
DC-228Please fix this issue.