diff --git a/lib/Doctrine/ORM/OptimisticLockException.php b/lib/Doctrine/ORM/OptimisticLockException.php index 57ea66bde..cadf4ce28 100644 --- a/lib/Doctrine/ORM/OptimisticLockException.php +++ b/lib/Doctrine/ORM/OptimisticLockException.php @@ -73,6 +73,8 @@ class OptimisticLockException extends ORMException */ public static function lockFailedVersionMismatch($entity, $expectedLockVersion, $actualLockVersion) { + $expectedLockVersion = (is_object($expectedLockVersion) && $expectedLockVersion instanceof \DateTime) ? $expectedLockVersion->getTimestamp() : $expectedLockVersion; + $actualLockVersion = (is_object($actualLockVersion) && $actualLockVersion instanceof \DateTime) ? $actualLockVersion->getTimestamp() : $actualLockVersion; return new self("The optimistic lock failed, version " . $expectedLockVersion . " was expected, but is actually ".$actualLockVersion, $entity); } diff --git a/tests/Doctrine/Tests/ORM/Functional/Locking/OptimisticTest.php b/tests/Doctrine/Tests/ORM/Functional/Locking/OptimisticTest.php index e2341a19e..cd0e04b02 100644 --- a/tests/Doctrine/Tests/ORM/Functional/Locking/OptimisticTest.php +++ b/tests/Doctrine/Tests/ORM/Functional/Locking/OptimisticTest.php @@ -7,6 +7,8 @@ use Doctrine\ORM\OptimisticLockException; use Doctrine\Common\EventManager; use Doctrine\ORM\Mapping\ClassMetadataFactory; use Doctrine\Tests\TestUtil; +use Doctrine\DBAL\LockMode; +use DateTime; require_once __DIR__ . '/../../../TestInit.php'; @@ -181,13 +183,44 @@ class OptimisticTest extends \Doctrine\Tests\OrmFunctionalTestCase $this->_conn->executeQuery('UPDATE optimistic_timestamp SET version = ? WHERE id = ?', array(date($format, strtotime($test->version->format($format)) + 3600), $test->id)); // Try and update the record and it should throw an exception + $caughtException = null; $test->name = 'Testing again'; try { $this->_em->flush(); } catch (OptimisticLockException $e) { - $this->assertSame($test, $e->getEntity()); + $caughtException = $e; } + + $this->assertNotNull($caughtException, "No OptimisticLockingException was thrown"); + $this->assertSame($test, $caughtException->getEntity()); + } + + /** + * @depends testOptimisticTimestampSetsDefaultValue + */ + public function testOptimisticTimestampLockFailureThrowsException(OptimisticTimestamp $entity) + { + $q = $this->_em->createQuery('SELECT t FROM Doctrine\Tests\ORM\Functional\Locking\OptimisticTimestamp t WHERE t.id = :id'); + $q->setParameter('id', $entity->id); + $test = $q->getSingleResult(); + + $this->assertInstanceOf('DateTime', $test->version); + + // Try to lock the record with an older timestamp and it should throw an exception + $caughtException = null; + try { + $expectedVersionExpired = DateTime::createFromFormat('U', $test->version->getTimestamp()-3600); + $this->_em->lock($test, LockMode::OPTIMISTIC, $expectedVersionExpired); + } catch (OptimisticLockException $e) { + $caughtException = $e; + } + + $this->assertNotNull($caughtException, "No OptimisticLockingException was thrown"); + $this->assertSame($test, $caughtException->getEntity()); + + } + } /**