使用StofDoctrineExtensionsBundle

时间:2017-10-03 17:58:19

标签: php symfony soft-delete doctrine-extensions

我期待,当我执行DELETE查询时,它应该更新deleted_at字段。它应该将deleted_at is null条件添加到SELECT查询的结尾。但它确实删除了具有愚蠢条件的行。有什么问题?

$query = $this->entityManager->createQueryBuilder()
    ->delete("AppBundle:ReportRow", "r")
    ->where("r.date <= :date")
    ->andWhere("r.balance is null")
    ->andWhere("r.name = :name")
    ->setParameters(array("date" => $date->format("Y-m-d"),
                            "name" => $user->getName()))
    ->getQuery();

$output->writeln($query->getSQL());

这是输出:

DELETE FROM report_row 
WHERE (date <= ? AND balance_id IS NULL AND name = ?) 
AND (report_row.deleted_at IS NULL) // really ?? its delete query dude!

这是我的配置

doctrine:
    ...
    orm:
        ...
        filters:
            softdeleteable:
                class: Gedmo\SoftDeleteable\Filter\SoftDeleteableFilter
                enabled: true

stof_doctrine_extensions:
    orm:
        default:
            softdeleteable: true

1 个答案:

答案 0 :(得分:0)

此问题已提交给开发人员,目前正在审核,自2014年起https://github.com/Atlantic18/DoctrineExtensions/issues/1125

<强>解释

当您使用QueryBuilder创建DELETE语句时,绕过onFlush事件侦听器,该侦听器用于防止实际删除条目,因为您不再在使用$em->remove($entity)时的实体管理器,而是手动发出SQL语句。

结果是,softdeletable过滤器不再管理您的查询意图,但仍然知道deleted_at元数据。

要解决此问题,您必须使用SoftDeleteableWalker的查询提示,如documentation

中所述
$query = $this->entityManager->createQueryBuilder()
    ->delete("AppBundle:ReportRow", "r")
    ->where("r.date <= :date")
    ->andWhere("r.balance is null")
    ->andWhere("r.name = :name")
    ->setParameters(array("date" => $date->format("Y-m-d"),
                            "name" => $user->getName()))
    ->getQuery();

$query->setHint(\Doctrine\ORM\Query::HINT_CUSTOM_OUTPUT_WALKER,
            \Gedmo\SoftDeleteable\Query\TreeWalker\SoftDeleteableWalker::class);

$output->writeln($query->getSQL());

结果:

UPDATE report_row 
SET deleted_at = '2017-10-03 15:06:48'
WHERE (date <= ? AND balance_id IS NULL AND name = ?)