【问题标题】:Odd many-to-many behavior in symfony 1.4 forms with Doctrine带有Doctrine的symfony 1.4表单中的奇数多对多行为
【发布时间】:2011-02-15 22:15:04
【问题描述】:

我在表单处理中遇到了意外的行为,symfony 1.4 with Doctrine。我有一个与自身有多对多关系的表:

Person:
  [...]
  relations:
    Teachers:
      class: Person
      refClass: PersonTeacher
      local: student_id
      foreign: teacher_id
      foreignAlias: Students

PersonTeacher:
  columns:
    teacher_id: { type: integer, primary: true }
    student_id: { type: integer, primary: true }

在 Person 中,我有一个在 PersonForm 中调用以用于自定义小部件的方法:

public function getTeachersOrderByName()
{
  $q = Doctrine::getTable('Person')
    ->createQuery('t')
    ->leftJoin('t.Students s')
    ->where('s.id = ?', $this->getId())
    ->orderBy('t.last_name, t.first_name ASC');

  return $q->execute();
}

如果没有该方法调用,Doctrine 会正确地从 PersonTeacher 插入和删除记录。但是当我从 PersonForm 调用该方法时,会在保存表单时运行以下更新 [取自日志]:

Doctrine_Connection->update(object('PersonTeacherTable'), array('student_id' => '9'), array('teacher_id' => '9', 'student_id' => '6'))

抛出

SQLSTATE[23000]: Integrity constraint violation: 19 columns teacher_id, student_id are not unique

回溯:

at Doctrine_Connection_Statement->execute(array('9', '9', '6'))
in SF_SYMFONY_LIB_DIR/plugins/sfDoctrinePlugin/lib/vendor/doctrine/Doctrine/Connection.php line 1042 ...
at Doctrine_Connection->exec('UPDATE person_teacher SET student_id = ? WHERE teacher_id = ? AND student_id = ?', array('9', '9', '6'))
in SF_SYMFONY_LIB_DIR/plugins/sfDoctrinePlugin/lib/vendor/doctrine/Doctrine/Connection.php line 653 ...
at Doctrine_Connection->update(object('PersonTeacherTable'), array('student_id' => '9'), array('teacher_id' => '9', 'student_id' => '6'))
in SF_SYMFONY_LIB_DIR/plugins/sfDoctrinePlugin/lib/vendor/doctrine/Doctrine/Connection/UnitOfWork.php line 534 ...
at Doctrine_Connection_UnitOfWork->update(object('PersonTeacher'))
in SF_SYMFONY_LIB_DIR/plugins/sfDoctrinePlugin/lib/vendor/doctrine/Doctrine/Connection/UnitOfWork.php line 89 ...
at Doctrine_Connection_UnitOfWork->saveGraph(object('PersonTeacher'))
in SF_SYMFONY_LIB_DIR/plugins/sfDoctrinePlugin/lib/vendor/doctrine/Doctrine/Record.php line 1718 ...
at Doctrine_Record->save(object('Doctrine_Connection_Sqlite'))
in SF_SYMFONY_LIB_DIR/plugins/sfDoctrinePlugin/lib/vendor/doctrine/Doctrine/Collection.php line 910 ...
at Doctrine_Collection->save(object('Doctrine_Connection_Sqlite'), 1)
in SF_SYMFONY_LIB_DIR/plugins/sfDoctrinePlugin/lib/vendor/doctrine/Doctrine/Connection/UnitOfWork.php line 136 ...
at Doctrine_Connection_UnitOfWork->saveGraph(object('Person'))
in SF_SYMFONY_LIB_DIR/plugins/sfDoctrinePlugin/lib/vendor/doctrine/Doctrine/Record.php line 1718 ...
at Doctrine_Record->save(object('Doctrine_Connection_Sqlite'))
in SF_SYMFONY_LIB_DIR/plugins/sfDoctrinePlugin/lib/vendor/doctrine/Doctrine/Collection.php line 910 ...
at Doctrine_Collection->save(object('Doctrine_Connection_Sqlite'), )
in SF_SYMFONY_LIB_DIR/plugins/sfDoctrinePlugin/lib/vendor/doctrine/Doctrine/Connection/UnitOfWork.php line 445 ...
at Doctrine_Connection_UnitOfWork->saveAssociations(object('Person'))
in SF_SYMFONY_LIB_DIR/plugins/sfDoctrinePlugin/lib/vendor/doctrine/Doctrine/Connection/UnitOfWork.php line 142 ...145.
at Doctrine_Connection_UnitOfWork->saveGraph(object('Person'))
in SF_SYMFONY_LIB_DIR/plugins/sfDoctrinePlugin/lib/vendor/doctrine/Doctrine/Record.php line 1718 ...
at Doctrine_Record->save(object('Doctrine_Connection_Sqlite'))
in SF_SYMFONY_LIB_DIR/form/addon/sfFormObject.class.php line 161 ...
at sfFormObject->doSave(object('Doctrine_Connection_Sqlite'))
in SF_ROOT_DIR/lib/form/doctrine/base/BasePersonForm.class.php line 116 ...
at BasePersonForm->doSave(object('Doctrine_Connection_Sqlite'))
in SF_SYMFONY_LIB_DIR/form/addon/sfFormObject.class.php line 130 ...

只有当多对多引用同一个表时才会发生这种情况。我也有一个一对多引用它自己的表,它工作正常。

这有什么铃声吗?

【问题讨论】:

  • 失败的约束对您来说是否正确?我同意这对 (teacher_id, student_id) 在 refClass 表中应该是唯一的,但单独的 teacher_id 不应该是唯一的,student_id 也不应该是唯一的。能否请您检查一下您的表结构并告诉我们对其施加了哪些约束?
  • @greg0ire:在我的 SQLite 数据库中创建的唯一约束是 PK(在 symfony 生成的 schema.sql 中确认),所以我认为错误是指 PK。问题是根本不应该调用 Doctrine_Connection::update() - PersonTeacher 记录应该只在需要时插入和删除,这确实会发生,直到我尝试调用我的 getTeachersOrderByName() 方法。这以某种方式打开了神秘的 update() 调用的大门。
  • CREATE TABLE person_teacher (teacher_id INTEGER, student_id INTEGER, PRIMARY KEY(teacher_id, student_id));
  • @yitznewton:在您的堆栈跟踪中,我可以看到“TeacherPerson”,在您的架构文件中,我只能看到“PersonTeacher”,用作 refClass ......怎么会?是否还有另一个 refClass,或者它更愿意是一个学说内部机制?
  • @yitznewton: 顺便说一句,您正在处理的是a non equal nested relation 正如您在链接页面中看到的那样,列被明确指定为主键的成员,也许您应该这样做在你的架构中?

标签: forms symfony1 doctrine many-to-many symfony-1.4


【解决方案1】:

【讨论】:

  • Doctrine 票证中的 h2aEqualable 解决方法似乎对我有用。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-12-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多