Skip to content

Commit

Permalink
Merge pull request #11564 from gitbugr/GH11501_fix_o2m_persister_sing…
Browse files Browse the repository at this point in the history
…le_inheritence_parent_relation_bugfix

GH11551 - fix OneToManyPersister::deleteEntityCollection case where single-inheritence table parent entity is targetEntity.
  • Loading branch information
greg0ire authored Aug 5, 2024
2 parents 51ad860 + 2707b09 commit 8ac6a13
Show file tree
Hide file tree
Showing 2 changed files with 129 additions and 3 deletions.
12 changes: 9 additions & 3 deletions src/Persisters/Collection/OneToManyPersister.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,13 @@
use Doctrine\ORM\PersistentCollection;
use Doctrine\ORM\Utility\PersisterHelper;

use function array_fill;
use function array_keys;
use function array_merge;
use function array_reverse;
use function array_values;
use function assert;
use function count;
use function implode;
use function is_int;
use function is_string;
Expand Down Expand Up @@ -194,9 +197,12 @@ private function deleteEntityCollection(PersistentCollection $collection): int

if ($targetClass->isInheritanceTypeSingleTable()) {
$discriminatorColumn = $targetClass->getDiscriminatorColumn();
$statement .= ' AND ' . $discriminatorColumn['name'] . ' = ?';
$parameters[] = $targetClass->discriminatorValue;
$types[] = $discriminatorColumn['type'];
$discriminatorValues = $targetClass->discriminatorValue ? [$targetClass->discriminatorValue] : array_keys($targetClass->discriminatorMap);
$statement .= ' AND ' . $discriminatorColumn['name'] . ' IN (' . implode(', ', array_fill(0, count($discriminatorValues), '?')) . ')';
foreach ($discriminatorValues as $discriminatorValue) {
$parameters[] = $discriminatorValue;
$types[] = $discriminatorColumn['type'];
}
}

$numAffected = $this->conn->executeStatement($statement, $parameters, $types);
Expand Down
120 changes: 120 additions & 0 deletions tests/Tests/ORM/Functional/Ticket/GH11501Test.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
<?php

declare(strict_types=1);

namespace Doctrine\Tests\ORM\Functional\Ticket;

use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Exception\ORMException;
use Doctrine\ORM\Mapping as ORM;
use Doctrine\Tests\OrmFunctionalTestCase;

class GH11501Test extends OrmFunctionalTestCase
{
protected function setUp(): void
{
parent::setUp();

$this->setUpEntitySchema([
GH11501AbstractTestEntity::class,
GH11501TestEntityOne::class,
GH11501TestEntityTwo::class,
GH11501TestEntityHolder::class,
]);
}

/**
* @throws ORMException
*/
public function testDeleteOneToManyCollectionWithSingleTableInheritance(): void
{
$testEntityOne = new GH11501TestEntityOne();
$testEntityTwo = new GH11501TestEntityTwo();
$testEntityHolder = new GH11501TestEntityHolder();

$testEntityOne->testEntityHolder = $testEntityHolder;
$testEntityHolder->testEntities->add($testEntityOne);

$testEntityTwo->testEntityHolder = $testEntityHolder;
$testEntityHolder->testEntities->add($testEntityTwo);

$em = $this->getEntityManager();
$em->persist($testEntityOne);
$em->persist($testEntityTwo);
$em->persist($testEntityHolder);
$em->flush();

$testEntityHolder->testEntities = new ArrayCollection();
$em->persist($testEntityHolder);
$em->flush();
$em->refresh($testEntityHolder);

static::assertEmpty($testEntityHolder->testEntities->toArray(), 'All records should have been deleted');
}
}



/**
* @ORM\Entity
* @ORM\Table(name="one_to_many_single_table_inheritance_test_entities_parent_join")
* @ORM\InheritanceType("SINGLE_TABLE")
* @ORM\DiscriminatorColumn(name="type", type="string")
* @ORM\DiscriminatorMap({"test_entity_one"="GH11501TestEntityOne", "test_entity_two"="GH11501TestEntityTwo"})
*/
class GH11501AbstractTestEntity
{
/**
* @ORM\Id
* @ORM\Column(type="integer")
* @ORM\GeneratedValue
*
* @var int
*/
public $id;

/**
* @ORM\ManyToOne(targetEntity="GH11501TestEntityHolder", inversedBy="testEntities")
* @ORM\JoinColumn(name="test_entity_holder_id", referencedColumnName="id")
*
* @var GH11501TestEntityHolder
*/
public $testEntityHolder;
}


/** @ORM\Entity */
class GH11501TestEntityOne extends GH11501AbstractTestEntity
{
}

/** @ORM\Entity */
class GH11501TestEntityTwo extends GH11501AbstractTestEntity
{
}

/** @ORM\Entity */
class GH11501TestEntityHolder
{
/**
* @ORM\Id
* @ORM\Column(type="integer")
* @ORM\GeneratedValue
*
* @var int
*/
public $id;

/**
* @ORM\OneToMany(targetEntity="GH11501AbstractTestEntity", mappedBy="testEntityHolder", orphanRemoval=true)
*
* @var Collection
*/
public $testEntities;

public function __construct()
{
$this->testEntities = new ArrayCollection();
}
}

0 comments on commit 8ac6a13

Please sign in to comment.