乐观锁定失败,因为Doctrine无法确定版本

时间:2014-12-28 22:27:42

标签: symfony doctrine-orm

我使用Doctrine 2并希望使用乐观锁定。它失败并显示OptimisticLockException,错误消息为The optimistic lock failed, version 1 was expected, but is actually。请注意,错误消息在“实际”之后停止。似乎Doctrine无法确定实体的版本。

我的简化实体代码是:

<?php
declare(encoding='UTF-8');

use Doctrine\ORM\Mapping as ORM;

/**
 * @ORM\Entity
 * @ORM\Table( name = "person" )
 */
class Person extends Entity  {

  /**
   * @param \string $firstName
   */
  public function __constructor( $firstName ) {
    parent::__constructor();
    $this->id = null;
    $this->revision = 0;
    $this->setFirstName( $firstName );
  }

  /**
   * @return int|null The id of the entity
   */
  public function getId() {
    return $this->id;
  }

  /**
   * @return int The revision of the entity
   */
  public function getRevision() {
    return $this->revision;
  }

  /**
   * @return \string The first name
   */
  public function getFirstName() {
    return $this->firstName;
  }

  /**
   * @param \string $newFirstName The new first name
   * @return Person The object itsself for function chaining
   */
  public function setFirstName( $newFirstName ) {
    $this->firstName = $newFirstName;
    return $this;
  }

  /**
   * @ORM\Id
   * @ORM\Column( name = "id", type = "integer" )
   * @ORM\GeneratedValue( strategy = "SEQUENCE" )
   * @var int
   */
  protected $id = null;

  /**
   * @ORM\Version
   * @ORM\Column( name = "rev", type = "integer" )
   * @var integer
   */
  protected $revision = null;

    /**
   * @ORM\Column( name = "firstname", type = "string", nullable = false )
   * @var \string
   */
  protected $firstName = null;
}

?>

进一步注意,正确的修订版(或版本)被加载到实体中。它等于1,可以通过getRevision()获得。因此,它不是数据库错误。

触发异常的代码是:

$em = $this->getDoctrine()->getManager();
$rep = $this->getDoctrine()->getRepository('HEKdbBundle:Person');
$person = $rep->find( $id );
$rev = $person->getRevision();
$em->lock( $person, LockMode::OPTIMISTIC, $rev );

(缩短的)回溯是:

  1. OptimisticLockException ::lockFailedVersionMismatch (object(Person), '1', null)

    /srv/www/matthiasn/vendor/doctrine/orm/lib/Doctrine/ORM/UnitOfWork.php第2320行

  2. UnitOfWork ->lock (object(Person), '1', '1')

    /srv/www/matthiasn/vendor/doctrine/orm/lib/Doctrine/ORM/EntityManager.php第747行

  3. EntityManager ->lock (object(Person), '1', '1')

    /srv/www/matthiasn/src/HEK/HEKdbBundle/Controller/PersonController.php第173行

  4. 可以看出,这不是$rev变量的问题。它完全等于1.实际上是UnitOfWork.php

    的第2317行
    $entityVersion = $class->reflFields[$class->versionField]->getValue($entity);
    

    失败。 $entityVersion等于null。但我不知道为什么,因为部分表达式$class->versionField是“revsion”。所以这不是我的实体注释的问题。

    如果有人能够理解它,这里是var_dump的{​​{1}}输出:

    $class$

1 个答案:

答案 0 :(得分:0)

解决方案很简单。懒加载欺骗了我。似乎->find并没有真正从数据库加载实体,但是这被推迟到一个访问实体的第一个属性。如果我插入$person->getFoo(),其中&#34; Foo&#34;表示在->find之后和->lock按预期工作之前的任意有效属性。