Skip to content

Commit ac33652

Browse files
committed
Failing test: Illegal to-many association on MappedSuperclass not rejected
This test case demonstrates a situation where an illegal to-many association on a mapped superclass is not being detected. Since at least the annotations and attribute drivers currently skip non-private properties from mapped superclasses (see doctrine#10417), the `ClassMetadataFactory` is not aware of the association on the mapped superclass at all and can not reject it. IMHO, we should bail out as soon as we detect this on the mapped superclass. I don't see how we could proceed at that time and try to rescue/fixup the situation afterwards. More details on what happens down the road, just for the sake of completeness: When the mapping driver processes the entity class with the inherited association, PHP reflection will report the association property. Since the association was not reported for the mapped superclass, the driver thinks (see doctrine#10417) this is a "new" (non-inherited) field and reports to the `ClassMetadataFactory`. The association will show up as being from `GH10449Entity` to `GH10449ToManyAssociationTarget`. On `GH10449ToManyAssociationTarget`, it will refer back to `GH10449MappedSuperclass`.
1 parent ed56f42 commit ac33652

File tree

1 file changed

+92
-0
lines changed

1 file changed

+92
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Doctrine\Tests\ORM\Functional\Ticket;
6+
7+
use Doctrine\Common\Collections\Collection;
8+
use Doctrine\ORM\Mapping as ORM;
9+
use Doctrine\ORM\Mapping\MappingException;
10+
use Doctrine\Tests\OrmTestCase;
11+
12+
use function get_parent_class;
13+
use function method_exists;
14+
15+
class GH10449Test extends OrmTestCase
16+
{
17+
public function testToManyAssociationOnMappedSuperclassShallBeRejected(): void
18+
{
19+
$em = $this->getTestEntityManager();
20+
$classes = [GH10449MappedSuperclass::class, GH10449Entity::class, GH10449ToManyAssociationTarget::class];
21+
22+
$this->expectException(MappingException::class);
23+
$this->expectExceptionMessageMatches('/illegal to put an inverse side one-to-many or many-to-many association on mapped superclass/');
24+
25+
foreach ($classes as $class) {
26+
$cm = $em->getClassMetadata($class);
27+
}
28+
}
29+
30+
/**
31+
* Override for BC with PHPUnit <8
32+
*/
33+
public function expectExceptionMessageMatches(string $regularExpression): void
34+
{
35+
if (method_exists(get_parent_class($this), 'expectExceptionMessageMatches')) {
36+
parent::expectExceptionMessageMatches($regularExpression);
37+
} else {
38+
parent::expectExceptionMessageRegExp($regularExpression);
39+
}
40+
}
41+
}
42+
43+
/**
44+
* @ORM\Entity
45+
*/
46+
class GH10449ToManyAssociationTarget
47+
{
48+
/**
49+
* @ORM\Column(type="integer")
50+
* @ORM\Id
51+
* @ORM\GeneratedValue
52+
*
53+
* @var int
54+
*/
55+
public $id;
56+
57+
/**
58+
* @ORM\ManyToOne(targetEntity="GH10449MappedSuperclass", inversedBy="targets")
59+
*
60+
* @var GH10449MappedSuperclass
61+
*/
62+
public $base;
63+
}
64+
65+
/**
66+
* @ORM\MappedSuperclass
67+
*/
68+
class GH10449MappedSuperclass
69+
{
70+
/**
71+
* @ORM\Column(type="integer")
72+
* @ORM\Id
73+
* @ORM\GeneratedValue
74+
*
75+
* @var int
76+
*/
77+
public $id;
78+
79+
/**
80+
* @ORM\OneToMany(targetEntity="GH10449ToManyAssociationTarget", mappedBy="base")
81+
*
82+
* @var Collection
83+
*/
84+
public $targets;
85+
}
86+
87+
/**
88+
* @ORM\Entity
89+
*/
90+
class GH10449Entity extends GH10449MappedSuperclass
91+
{
92+
}

0 commit comments

Comments
 (0)