Gedmo\Loggable记录未更改的数据

rab*_*dde 8 symfony doctrine-orm doctrine-extensions symfony-2.2 stofdoctrineextensions

我正在使用Symfony2.2和StofDoctrineExtensionsBundle(以及Gedmo DoctrineExtensions).我有一个简单的实体

/**
 * @ORM\Entity
 * @Gedmo\Loggable
 * @ORM\Table(name="person")
 */
class Person {
    /**
     * @ORM\Id
     * @ORM\Column(type="integer")
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    protected $id;

[...]

    /**
     * @ORM\Column(type="datetime", nullable=true)
     * @Assert\NotBlank()
     * @Assert\Date()
     * @Gedmo\Versioned
     */
    protected $birthdate;
}
Run Code Online (Sandbox Code Playgroud)

更改现有对象的属性时,将在表中完成日志条目ext_log_entries.此日志表中的条目仅包含已更改的列.我可以通过以下方式阅读日志:

$em = $this->getManager();
$repo = $em->getRepository('Gedmo\Loggable\Entity\LogEntry');
$person_repo = $em->getRepository('Acme\MainBundle\Entity\Person');

$person = $person_repo->find(1);
$log = $repo->findBy(array('objectId' => $person->getId()));
foreach ($log as $log_entry) { var_dump($log_entry->getData()); }
Run Code Online (Sandbox Code Playgroud)

但我不明白的是,为什么字段birthdate总是包含在日志条目中,即使它没有改变.这里有一些三个日志条目的例子:

array(9) {
  ["salutation"]=>
  string(4) "Herr"
  ["firstname"]=>
  string(3) "Max"
  ["lastname"]=>
  string(6) "Muster"
  ["street"]=>
  string(14) "Musterstraße 1"
  ["zipcode"]=>
  string(5) "00000"
  ["city"]=>
  string(12) "Musterhausen"
  ["birthdate"]=>
  object(DateTime)#655 (3) {
    ["date"]=>
    string(19) "1893-01-01 00:00:00"
    ["timezone_type"]=>
    int(3)
    ["timezone"]=>
    string(13) "Europe/Berlin"
  }
  ["email"]=>
  string(17) "email@example.com"
  ["phone"]=>
  NULL
}

array(2) {
  ["birthdate"]=>
  object(DateTime)#659 (3) {
    ["date"]=>
    string(19) "1893-01-01 00:00:00"
    ["timezone_type"]=>
    int(3)
    ["timezone"]=>
    string(13) "Europe/Berlin"
  }
  ["phone"]=>
  string(9) "123456789"
}

array(2) {
  ["birthdate"]=>
  object(DateTime)#662 (3) {
    ["date"]=>
    string(19) "1893-01-01 00:00:00"
    ["timezone_type"]=>
    int(3)
    ["timezone"]=>
    string(13) "Europe/Berlin"
  }
  ["phone"]=>
  NULL
}
Run Code Online (Sandbox Code Playgroud)

我想只记录真正改变的数据.有没有我没见过的选择?它似乎与事实有关,那birthdate是一个DateTime对象,不是吗?

编辑 它与DateTime对象无关.这甚至在其他实体中也会发生.我有另一个包含简单值的实体:

/**
 * @ORM\Entity
 * @Gedmo\Loggable
 * @ORM\Entity(repositoryClass="Acme\MainBundle\Repository\ApplicationRepository")
 * @ORM\Table(name="application")
 */
class Application {

[...]

    /**
     * @ORM\Column(type="integer")
     * @Assert\NotBlank(groups={"FormStepOne", "UserEditApplication"})
     * @Gedmo\Versioned
     */
    protected $insurance_number;
}
Run Code Online (Sandbox Code Playgroud)

在浏览器中打开编辑表单时保存而不进行修改,日志表包含:

update  2013-04-26 11:32:42     Acme\MainBundle\Entity\Application  a:1:{s:16:"insurance_number";s:7:"1234567";}
update  2013-04-26 11:33:17     Acme\MainBundle\Entity\Application  a:1:{s:16:"insurance_number";s:7:"1234567";}
Run Code Online (Sandbox Code Playgroud)

为什么?

cal*_*die 7

这可能是一个类似的问题我用另一个这些扩展(timestampable)时,即遇到了一个:在教义使用的默认更改跟踪政策(它会尝试自动检测更改)有时标志着实体脏,当他们不(对我来说,当我的实体包含一个日期时间对象时就会发生这种情况,这是可以理解的,因为这是一个在从数据库中提取时需要构造的对象).这不是一个错误或任何东西 - 它是预期的行为,并有几种方法围绕它.

可能值得尝试在您要记录的实体上实现替代更改跟踪策略,并查看是否可以修复问题 - 我猜这种行为(日志记录)不会启动,除非实体状态是脏的,您可以避免通过手动实施更改跟踪:

http://docs.doctrine-project.org/en/latest/cookbook/implementing-the-notify-changetracking-policy.html

不要忘记更新您的实体:

YourBundle\Entity\YourThing:
    type: entity
    table: some_table
    changeTrackingPolicy: NOTIFY
Run Code Online (Sandbox Code Playgroud)

看到这个帖子:

https://github.com/Atlantic18/DoctrineExtensions/issues/333#issuecomment-16738878