Skip to content

Commit 9a0fcb5

Browse files
authored
Merge pull request #7940 from doctrine/GH-7864-ExtraLazyRemoveElement
[GH-7864] Bugfix in PersistentCollection::removeElement for EXTRA_LAZY.
2 parents 8104c65 + 041404e commit 9a0fcb5

File tree

9 files changed

+255
-668
lines changed

9 files changed

+255
-668
lines changed

docs/en/tutorials/extra-lazy-associations.rst

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,15 @@ With extra lazy collections you can now not only add entities to large collectio
3535
easily using a combination of ``count`` and ``slice``.
3636

3737

38+
.. warning::
39+
40+
``removeElement`` directly issued DELETE queries to the database from
41+
version 2.4.0 to 2.7.0. This circumvents the flush operation and might run
42+
outside a transactional boundary if you don't create one yourself. We
43+
consider this a critical bug in the assumptio of how the ORM works and
44+
reverted ``removeElement`` EXTRA_LAZY behavior in 2.7.1.
45+
46+
3847
Enabling Extra-Lazy Associations
3948
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
4049

lib/Doctrine/ORM/Cache/Persister/Collection/AbstractCollectionPersister.php

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -243,20 +243,6 @@ public function get(PersistentCollection $collection, $index)
243243
return $this->persister->get($collection, $index);
244244
}
245245

246-
/**
247-
* {@inheritdoc}
248-
*/
249-
public function removeElement(PersistentCollection $collection, $element)
250-
{
251-
if ($persisterResult = $this->persister->removeElement($collection, $element)) {
252-
$this->evictCollectionCache($collection);
253-
$this->evictElementCache($this->sourceEntity->rootEntityName, $collection->getOwner());
254-
$this->evictElementCache($this->targetEntity->rootEntityName, $element);
255-
}
256-
257-
return $persisterResult;
258-
}
259-
260246
/**
261247
* {@inheritdoc}
262248
*/

lib/Doctrine/ORM/PersistentCollection.php

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -367,16 +367,6 @@ public function remove($key)
367367
*/
368368
public function removeElement($element)
369369
{
370-
if ( ! $this->initialized && $this->association['fetch'] === ClassMetadata::FETCH_EXTRA_LAZY) {
371-
if ($this->collection->contains($element)) {
372-
return $this->collection->removeElement($element);
373-
}
374-
375-
$persister = $this->em->getUnitOfWork()->getCollectionPersister($this->association);
376-
377-
return $persister->removeElement($this, $element);
378-
}
379-
380370
$removed = parent::removeElement($element);
381371

382372
if ( ! $removed) {

lib/Doctrine/ORM/Persisters/Collection/CollectionPersister.php

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -90,16 +90,6 @@ public function contains(PersistentCollection $collection, $element);
9090
*/
9191
public function containsKey(PersistentCollection $collection, $key);
9292

93-
/**
94-
* Removes an element.
95-
*
96-
* @param \Doctrine\ORM\PersistentCollection $collection
97-
* @param object $element
98-
*
99-
* @return mixed
100-
*/
101-
public function removeElement(PersistentCollection $collection, $element);
102-
10393
/**
10494
* Gets an element by key.
10595
*

lib/Doctrine/ORM/Persisters/Collection/ManyToManyPersister.php

Lines changed: 0 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -211,22 +211,6 @@ public function contains(PersistentCollection $collection, $element)
211211
return (bool) $this->conn->fetchColumn($sql, $params, 0, $types);
212212
}
213213

214-
/**
215-
* {@inheritDoc}
216-
*/
217-
public function removeElement(PersistentCollection $collection, $element)
218-
{
219-
if ( ! $this->isValidEntityState($element)) {
220-
return false;
221-
}
222-
223-
list($quotedJoinTable, $whereClauses, $params, $types) = $this->getJoinTableRestrictions($collection, $element, false);
224-
225-
$sql = 'DELETE FROM ' . $quotedJoinTable . ' WHERE ' . implode(' AND ', $whereClauses);
226-
227-
return (bool) $this->conn->executeUpdate($sql, $params, $types);
228-
}
229-
230214
/**
231215
* {@inheritDoc}
232216
*/

lib/Doctrine/ORM/Persisters/Collection/OneToManyPersister.php

Lines changed: 0 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -166,28 +166,6 @@ public function contains(PersistentCollection $collection, $element)
166166
return $persister->exists($element, $criteria);
167167
}
168168

169-
/**
170-
* {@inheritdoc}
171-
*/
172-
public function removeElement(PersistentCollection $collection, $element)
173-
{
174-
$mapping = $collection->getMapping();
175-
176-
if ( ! $mapping['orphanRemoval']) {
177-
// no-op: this is not the owning side, therefore no operations should be applied
178-
return false;
179-
}
180-
181-
if ( ! $this->isValidEntityState($element)) {
182-
return false;
183-
}
184-
185-
return $this
186-
->uow
187-
->getEntityPersister($mapping['targetEntity'])
188-
->delete($element);
189-
}
190-
191169
/**
192170
* {@inheritdoc}
193171
*/

tests/Doctrine/Tests/ORM/Cache/Persister/Collection/AbstractCollectionPersisterTest.php

Lines changed: 0 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -227,23 +227,6 @@ public function testInvokeContainsKey()
227227
$this->assertFalse($persister->containsKey($collection, 0));
228228
}
229229

230-
public function testInvokeRemoveElement()
231-
{
232-
$entity = new State("Foo");
233-
$element = new State("Bar");
234-
$persister = $this->createPersisterDefault();
235-
$collection = $this->createCollection($entity);
236-
237-
$this->em->getUnitOfWork()->registerManaged($entity, ['id'=>1], ['id'=>1, 'name'=>'Foo']);
238-
239-
$this->collectionPersister->expects($this->once())
240-
->method('removeElement')
241-
->with($this->equalTo($collection), $this->equalTo($element))
242-
->will($this->returnValue(false));
243-
244-
$this->assertFalse($persister->removeElement($collection, $element));
245-
}
246-
247230
public function testInvokeGet()
248231
{
249232
$entity = new State("Foo");

0 commit comments

Comments
 (0)