Commit 94d77117 authored by romanb's avatar romanb

[2.0][DDC-74] Fixed.

parent 3a282b1e
......@@ -613,15 +613,22 @@ class UnitOfWork implements PropertyChangedListener
* Computes the changeset of an individual entity, independently of the
* computeChangeSets() routine that is used at the beginning of a UnitOfWork#commit().
*
* The passed entity must be a managed entity.
* The passed entity must be a managed entity. If the entity already has a change set
* because this method is invoked during a commit cycle then the change sets are added.
* whereby changes detected in this method prevail.
*
* @ignore
* @param $class
* @param $entity
* @param ClassMetadata $class The class descriptor of the entity.
* @param object $entity The entity for which to (re)calculate the change set.
* @throws InvalidArgumentException If the passed entity is not MANAGED.
*/
public function computeSingleEntityChangeSet($class, $entity)
{
$oid = spl_object_hash($entity);
if ( ! isset($this->_entityStates[$oid]) || $this->_entityStates[$oid] != self::STATE_MANAGED) {
throw new \InvalidArgumentException('Entity must be managed.');
}
if ( ! $class->isInheritanceTypeNone()) {
$class = $this->_em->getClassMetadata(get_class($entity));
......@@ -634,28 +641,23 @@ class UnitOfWork implements PropertyChangedListener
}
}
if ( ! isset($this->_originalEntityData[$oid])) {
$this->_originalEntityData[$oid] = $actualData;
$this->_entityChangeSets[$oid] = array_map(
function($e) { return array(null, $e); }, $actualData
);
} else {
$originalData = $this->_originalEntityData[$oid];
$changeSet = array();
foreach ($actualData as $propName => $actualValue) {
$orgValue = isset($originalData[$propName]) ? $originalData[$propName] : null;
if (is_object($orgValue) && $orgValue !== $actualValue) {
$changeSet[$propName] = array($orgValue, $actualValue);
} else if ($orgValue != $actualValue || ($orgValue === null ^ $actualValue === null)) {
$changeSet[$propName] = array($orgValue, $actualValue);
}
$originalData = $this->_originalEntityData[$oid];
$changeSet = array();
foreach ($actualData as $propName => $actualValue) {
$orgValue = isset($originalData[$propName]) ? $originalData[$propName] : null;
if (is_object($orgValue) && $orgValue !== $actualValue) {
$changeSet[$propName] = array($orgValue, $actualValue);
} else if ($orgValue != $actualValue || ($orgValue === null ^ $actualValue === null)) {
$changeSet[$propName] = array($orgValue, $actualValue);
}
if ($changeSet) {
$this->_entityChangeSets[$oid] = $changeSet;
$this->_originalEntityData[$oid] = $actualData;
}
if ($changeSet) {
if (isset($this->_entityChangeSets[$oid])) {
$this->_entityChangeSets[$oid] = $changeSet + $this->_entityChangeSets[$oid];
}
$this->_originalEntityData[$oid] = $actualData;
}
}
......
......@@ -10,7 +10,8 @@ class LifecycleCallbackTest extends \Doctrine\Tests\OrmFunctionalTestCase
parent::setUp();
try {
$this->_schemaTool->createSchema(array(
$this->_em->getClassMetadata('Doctrine\Tests\ORM\Functional\LifecycleCallbackTestEntity')
$this->_em->getClassMetadata('Doctrine\Tests\ORM\Functional\LifecycleCallbackTestEntity'),
$this->_em->getClassMetadata('Doctrine\Tests\ORM\Functional\LifecycleCallbackTestUser')
));
} catch (\Exception $e) {
// Swallow all exceptions. We do not test the schema tool here.
......@@ -39,6 +40,42 @@ class LifecycleCallbackTest extends \Doctrine\Tests\OrmFunctionalTestCase
$this->assertEquals('changed from preUpdate callback!', $result[0]->value);
}
public function testChangesDontGetLost()
{
$user = new LifecycleCallbackTestUser;
$user->setName('Bob');
$user->setValue('');
$this->_em->persist($user);
$this->_em->flush();
$user->setName('Alice');
$this->_em->flush(); // Triggers preUpdate
$this->_em->clear();
$user2 = $this->_em->find(get_class($user), $user->getId());
$this->assertEquals('Alice', $user2->getName());
$this->assertEquals('Hello World', $user2->getValue());
}
}
/** @Entity @HasLifecycleCallbacks */
class LifecycleCallbackTestUser {
/** @Id @Column(type="integer") @GeneratedValue(strategy="AUTO") */
private $id;
/** @Column(type="string") */
private $value;
/** @Column(type="string") */
private $name;
public function getId() {return $this->id;}
public function getValue() {return $this->value;}
public function setValue($value) {$this->value = $value;}
public function getName() {return $this->name;}
public function setName($name) {$this->name = $name;}
/** @PreUpdate */
public function testCallback() {$this->value = 'Hello World';}
}
/**
......@@ -59,7 +96,7 @@ class LifecycleCallbackTestEntity
*/
private $id;
/**
* @Column(type="string", length=255)
* @Column(type="string")
*/
public $value;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment