Skip to content

Commit 2f46669

Browse files
committed
Association with primary key is never nullable
1 parent f7c3d5e commit 2f46669

File tree

4 files changed

+70
-1
lines changed

4 files changed

+70
-1
lines changed

src/Rules/Doctrine/ORM/EntityRelationRule.php

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,11 +67,25 @@ public function processNode(Node $node, Scope $scope): array
6767
return [];
6868
}
6969
$associationMapping = $metadata->associationMappings[$propertyName];
70+
$identifier = null;
71+
try {
72+
$identifier = $metadata->getSingleIdentifierFieldName();
73+
} catch (\Throwable $e) {
74+
$mappingException = 'Doctrine\ORM\Mapping\MappingException';
75+
if (!$e instanceof $mappingException) {
76+
throw $e;
77+
}
78+
}
7079

7180
$columnType = null;
7281
if ((bool) ($associationMapping['type'] & 3)) { // ClassMetadataInfo::TO_ONE
7382
$columnType = new ObjectType($associationMapping['targetEntity']);
74-
if ($associationMapping['joinColumns'][0]['nullable'] ?? true) {
83+
if ($identifier !== null && $identifier === $propertyName) {
84+
$nullable = false;
85+
} else {
86+
$nullable = $associationMapping['joinColumns'][0]['nullable'] ?? true;
87+
}
88+
if ($nullable) {
7589
$columnType = TypeCombinator::addNull($columnType);
7690
}
7791
} elseif ((bool) ($associationMapping['type'] & 12)) { // ClassMetadataInfo::TO_MANY

tests/Rules/Doctrine/ORM/EntityRelationRuleTest.php

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,21 @@ public function ruleProvider(): Iterator
116116
36,
117117
],
118118
]];
119+
120+
yield 'primary key as relation' => [
121+
__DIR__ . '/data/MyEntityRelationPrimaryKey.php',
122+
[],
123+
];
124+
125+
yield 'primary key as nullable relation' => [
126+
__DIR__ . '/data/MyEntityRelationNullablePrimaryKey.php',
127+
[
128+
[
129+
'Property PHPStan\Rules\Doctrine\ORM\MyEntityRelationNullablePrimaryKey::$id type mapping mismatch: property can contain PHPStan\Rules\Doctrine\ORM\MyEntity|null but database expects PHPStan\Rules\Doctrine\ORM\MyEntity.',
130+
18,
131+
],
132+
],
133+
];
119134
}
120135

121136
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
<?php declare(strict_types = 1);
2+
3+
namespace PHPStan\Rules\Doctrine\ORM;
4+
5+
use Doctrine\ORM\Mapping as ORM;
6+
7+
/**
8+
* @ORM\Entity()
9+
*/
10+
class MyEntityRelationNullablePrimaryKey
11+
{
12+
/**
13+
* @ORM\Id()
14+
* @ORM\ManyToOne(targetEntity=MyEntity::class)
15+
*
16+
* @var MyEntity|null
17+
*/
18+
private $id;
19+
20+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
<?php declare(strict_types = 1);
2+
3+
namespace PHPStan\Rules\Doctrine\ORM;
4+
5+
use Doctrine\ORM\Mapping as ORM;
6+
7+
/**
8+
* @ORM\Entity()
9+
*/
10+
class MyEntityRelationPrimaryKey
11+
{
12+
/**
13+
* @ORM\Id()
14+
* @ORM\ManyToOne(targetEntity=MyEntity::class)
15+
*
16+
* @var MyEntity
17+
*/
18+
private $id;
19+
20+
}

0 commit comments

Comments
 (0)