Doctrine SoftDelete更新父表

时间:2012-11-03 11:58:18

标签: symfony1 doctrine symfony-1.4 doctrine-1.2

我有一个注释表,用于存储3个不同表中对象的注释。当我在删除其中一个对象的注释上运行功能测试时,它工作正常。但是,如果我运行一个功能测试来删除其他一个对象的注释,我得到一个完整性约束MySQL错误,因为doctrine试图“更新”第一个对象表,作为删除与表中对象关联的注释的一部分b或c。我无法弄清楚为什么删除评论试图更新父表。

从3个对象表中的每一个到注释表都有一个删除级联。这些表在Symfony 1.4中以YML定义

object_a:
  columns:
    some stuff
  relations:
    Comments:
      class: Comments
      local: id
      foreign: object_a_id
      type: many
      foreignType: one
      cascade: [delete]

object_b:
  columns:
    some stuff
  relations:
    Comments:
      class: Comments
      local: id
      foreign: object_b_id
      type: many
      foreignType: one
      cascade: [delete]

object_c:
  columns:
    some stuff
  relations:
    Comments:
      class: Comments
      local: id
      foreign: object_c_id
      type: many
      foreignType: one
      cascade: [delete]

comments:
  columns:
    object_a_id:
       type: integer(4)
    object_b_id
       type: integer(4)
    object_c_id
       type: integer(4)
  relations:
    Object_a:
       local: object_a_id
       foreign: id
       type: one
    Object_b:
       local: object_b_id
       foreign: id
       type: one
    Object_c:
       local: object_c_id
       foreign: id
       type: one

仅在通过Symfony 1.4测试工具运行测试时才会出现此故障。它在开发环境中工作正常。在对象b和c被添加之前,对象a是必填字段但是已被删除。我运行symfony cache:clear --env = test查看是否删除了任何可能干扰的缓存的doctrine对象。

修改 现在遇到生产中的问题&发展。据我所知,从数据模块和BaseModel文件中没有理由更新父表。

1 个答案:

答案 0 :(得分:1)

在经历了很多焦虑和头脑撞击之后,我弄清楚这里发生了什么。

在这种情况下,架构或生成的PHP都没有任何问题。相反,它是由于子类中的postSave()操作而发生的。 postSave()动作是获取父类的属性,该属性已被删除,因此Doctrine实际上创建了一个新对象,然后它尝试将其保存为工作单元的一部分。由于新对象没有任何必需字段,因此MySQL出错了。

一个例子应该让它更清晰。 Object A是具有Object B孩子的父对象。 Object A有一个属性foo

$object_a->delete();

会触发postSave()中的Object B操作。这个动作是:

function postSave($event) 
{
  //do something
  $slug = $this->Object_As->foo;
  //do more stuff
}

$this->Object_As->foo或使用事件$event->getInvoker()->getFoo()如果不存在,将尝试创建Object_A。现在,有趣的一点是,如果你的MySQL表没有必需的字段,这可能会导致创建大量新的Object_A而你不知道它,直到它在其他地方引起问题。我怀疑追查罪魁祸首是非常困难的。

在我的实际用例中,我正在删除缓存元素。当我使用softDelete时,我通过检查invoker删除字段是否为空来解决它:

$event->getInvoker()->getDeleted_at()