1
0
mirror of synced 2025-02-21 14:43:14 +03:00

[2.0] fixes #2478 Now PersistentCollections may contain NEW elements and track policy monitor them when flushing on DEFER_IMPLICIT mode

This commit is contained in:
guilhermeblanco 2009-09-06 03:25:44 +00:00
parent 788312e1fc
commit 686758e846
3 changed files with 22 additions and 10 deletions

View File

@ -141,11 +141,7 @@ class ObjectHydrator extends AbstractHydrator
$pColl = new PersistentCollection( $pColl = new PersistentCollection(
$this->_em, $this->_em,
$this->_ce[$relation->targetEntityName], $this->_ce[$relation->targetEntityName],
/*
TICKET #2478: This seems to double resultset in Collections after add/persist/retrieve execution
$class->reflFields[$name]->getValue($entity) ?: new ArrayCollection $class->reflFields[$name]->getValue($entity) ?: new ArrayCollection
*/
new ArrayCollection()
); );
$pColl->setOwner($entity, $relation); $pColl->setOwner($entity, $relation);

View File

@ -134,6 +134,7 @@ final class PersistentCollection implements \Doctrine\Common\Collections\Collect
{ {
$this->_owner = $entity; $this->_owner = $entity;
$this->_association = $assoc; $this->_association = $assoc;
// Check for bidirectionality // Check for bidirectionality
if ( ! $assoc->isOwningSide) { if ( ! $assoc->isOwningSide) {
// For sure bi-directional // For sure bi-directional
@ -176,7 +177,10 @@ final class PersistentCollection implements \Doctrine\Common\Collections\Collect
*/ */
public function hydrateAdd($element) public function hydrateAdd($element)
{ {
$this->_coll->add($element); if ( ! $this->contains($element)) {
$this->_coll->add($element);
}
// If _backRefFieldName is set, then the association is bidirectional // If _backRefFieldName is set, then the association is bidirectional
// and we need to set the back reference. // and we need to set the back reference.
if ($this->_backRefFieldName) { if ($this->_backRefFieldName) {
@ -202,7 +206,10 @@ final class PersistentCollection implements \Doctrine\Common\Collections\Collect
*/ */
public function hydrateSet($key, $element) public function hydrateSet($key, $element)
{ {
$this->_coll->set($key, $element); if ( ! $this->contains($element)) {
$this->_coll->set($key, $element);
}
// If _backRefFieldName is set, then the association is bidirectional // If _backRefFieldName is set, then the association is bidirectional
// and we need to set the back reference. // and we need to set the back reference.
if ($this->_backRefFieldName) { if ($this->_backRefFieldName) {

View File

@ -451,16 +451,25 @@ class UnitOfWork implements PropertyChangedListener
$actualData[$name] = $refProp->getValue($entity); $actualData[$name] = $refProp->getValue($entity);
} }
if ($class->isCollectionValuedAssociation($name) && $actualData[$name] !== null if ($class->isCollectionValuedAssociation($name) && $actualData[$name] !== null) {
&& ! ($actualData[$name] instanceof PersistentCollection)) {
// If $actualData[$name] is Collection then unwrap the array // If $actualData[$name] is Collection then unwrap the array
if ( ! $actualData[$name] instanceof ArrayCollection) { if ( ! $actualData[$name] instanceof ArrayCollection) {
if ($actualData[$name] instanceof PersistentCollection) {
$actualData[$name] = $actualData[$name]->toArray();
}
$actualData[$name] = new ArrayCollection($actualData[$name]); $actualData[$name] = new ArrayCollection($actualData[$name]);
} }
$assoc = $class->associationMappings[$name]; $assoc = $class->associationMappings[$name];
// Inject PersistentCollection // Inject PersistentCollection
$coll = new PersistentCollection($this->_em, $this->_em->getClassMetadata( $coll = new PersistentCollection(
$assoc->targetEntityName), $actualData[$name]); $this->_em,
$this->_em->getClassMetadata($assoc->targetEntityName),
$actualData[$name]
);
$coll->setOwner($entity, $assoc); $coll->setOwner($entity, $assoc);
$coll->setDirty( ! $coll->isEmpty()); $coll->setDirty( ! $coll->isEmpty());
$class->reflFields[$name]->setValue($entity, $coll); $class->reflFields[$name]->setValue($entity, $coll);