Skip to content

Commit 03cc07e

Browse files
authored
Merge pull request doctrine#12137 from greg0ire/forbid-nullable-on-primary-key
Forbid nullable on columns that are part of a primary key
2 parents 0c73cf9 + 78fee8e commit 03cc07e

9 files changed

+45
-70
lines changed

UPGRADE.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
11
# Upgrade to 4.0
22

3+
## BC BREAK: throw on `nullable` on columns that end up being used in a primary key
4+
5+
Specifying `nullable` on join columns that are part of a primary key is
6+
an error and will cause an exception to be thrown.
7+
38
## BC BREAK: `Doctrine\ORM\Mapping\LegacyReflectionFields` is removed
49

510
The `Doctrine\ORM\Mapping\LegacyReflectionFields` class has been removed.

src/Mapping/ManyToManyOwningSideMapping.php

Lines changed: 2 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,6 @@
44

55
namespace Doctrine\ORM\Mapping;
66

7-
use Doctrine\Deprecations\Deprecation;
8-
97
use function strtolower;
108
use function trim;
119

@@ -130,14 +128,7 @@ public static function fromMappingArrayAndNamingStrategy(array $mappingArray, Na
130128

131129
foreach ($mapping->joinTable->joinColumns as $joinColumn) {
132130
if ($joinColumn->nullable !== null) {
133-
Deprecation::trigger(
134-
'doctrine/orm',
135-
'https://github/doctrine/orm/pull/12125',
136-
<<<'DEPRECATION'
137-
Specifying the "nullable" attribute for join columns in many-to-many associations (here, %s::$%s) is a no-op.
138-
The ORM will always set it to false.
139-
Doing so is deprecated and will be an error in 4.0.
140-
DEPRECATION,
131+
throw MappingException::cannotSetNullableOnManyToManyJoinColumns(
141132
$mapping->sourceEntity,
142133
$mapping->fieldName,
143134
);
@@ -169,14 +160,7 @@ public static function fromMappingArrayAndNamingStrategy(array $mappingArray, Na
169160

170161
foreach ($mapping->joinTable->inverseJoinColumns as $inverseJoinColumn) {
171162
if ($inverseJoinColumn->nullable !== null) {
172-
Deprecation::trigger(
173-
'doctrine/orm',
174-
'https://github/doctrine/orm/pull/12125',
175-
<<<'DEPRECATION'
176-
Specifying the "nullable" attribute for join columns in many-to-many associations (here, %s::$%s) is a no-op.
177-
The ORM will always set it to false.
178-
Doing so is deprecated and will be an error in 4.0.
179-
DEPRECATION,
163+
throw MappingException::cannotSetNullableOnManyToManyJoinColumns(
180164
$mapping->targetEntity,
181165
$mapping->fieldName,
182166
);

src/Mapping/MappingException.php

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -406,6 +406,28 @@ public static function nameIsMandatoryForDiscriminatorColumns(string $className)
406406
return new self(sprintf("Discriminator column name on entity class '%s' is not defined.", $className));
407407
}
408408

409+
public static function cannotSetNullableOnToOneIdentifierJoinColumns(
410+
string $className,
411+
string $fieldName,
412+
): self {
413+
return new self(sprintf(
414+
'Cannot specify the "nullable" attribute for join columns in to-one associations (%s::$%s) that are part of the identifier',
415+
$className,
416+
$fieldName,
417+
));
418+
}
419+
420+
public static function cannotSetNullableOnManyToManyJoinColumns(
421+
string $className,
422+
string $fieldName,
423+
): self {
424+
return new self(sprintf(
425+
'Cannot specify the "nullable" attribute for join columns in many-to-many associations (%s::$%s)',
426+
$className,
427+
$fieldName,
428+
));
429+
}
430+
409431
public static function cannotVersionIdField(string $className, string $fieldName): self
410432
{
411433
return new self(sprintf(

src/Mapping/ToOneOwningSideMapping.php

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44

55
namespace Doctrine\ORM\Mapping;
66

7-
use Doctrine\Deprecations\Deprecation;
87
use RuntimeException;
98

109
use function array_flip;
@@ -133,14 +132,7 @@ public static function fromMappingArrayAndName(
133132
foreach ($mapping->joinColumns as $joinColumn) {
134133
if ($mapping->id) {
135134
if ($joinColumn->nullable !== null) {
136-
Deprecation::trigger(
137-
'doctrine/orm',
138-
'https://github/doctrine/orm/pull/12125',
139-
<<<'DEPRECATION'
140-
Specifying the "nullable" attribute for join columns in to-one associations (here, %s::$%s) that are part of the identifier is a no-op.
141-
The ORM will always set it to false.
142-
Doing so is deprecated and will be an error in 4.0.
143-
DEPRECATION,
135+
throw MappingException::cannotSetNullableOnToOneIdentifierJoinColumns(
144136
$mapping->sourceEntity,
145137
$mapping->fieldName,
146138
);

tests/Tests/ORM/Mapping/ManyToManyOwningSideMappingTest.php

Lines changed: 5 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,11 @@
44

55
namespace Doctrine\Tests\ORM\Mapping;
66

7-
use Doctrine\Deprecations\PHPUnit\VerifyDeprecations;
87
use Doctrine\ORM\Mapping\DefaultNamingStrategy;
98
use Doctrine\ORM\Mapping\JoinTableMapping;
109
use Doctrine\ORM\Mapping\ManyToManyOwningSideMapping;
10+
use Doctrine\ORM\Mapping\MappingException;
1111
use PHPUnit\Framework\Attributes\DataProvider;
12-
use PHPUnit\Framework\Attributes\WithoutErrorHandler;
1312
use PHPUnit\Framework\TestCase;
1413

1514
use function assert;
@@ -18,8 +17,6 @@
1817

1918
final class ManyToManyOwningSideMappingTest extends TestCase
2019
{
21-
use VerifyDeprecations;
22-
2320
public function testItSurvivesSerialization(): void
2421
{
2522
$mapping = new ManyToManyOwningSideMapping(
@@ -44,20 +41,15 @@ public function testItSurvivesSerialization(): void
4441

4542
/** @param array<string,mixed> $mappingArray */
4643
#[DataProvider('mappingsProvider')]
47-
#[WithoutErrorHandler]
4844
public function testNullableDefaults(
49-
bool $expectDeprecation,
45+
bool $expectException,
5046
bool $expectedValue,
5147
array $mappingArray,
5248
): void {
5349
$namingStrategy = new DefaultNamingStrategy();
54-
if ($expectDeprecation) {
55-
$this->expectDeprecationWithIdentifier(
56-
'https://github/doctrine/orm/pull/12125',
57-
);
58-
} else {
59-
$this->expectNoDeprecationWithIdentifier(
60-
'https://github/doctrine/orm/pull/12125',
50+
if ($expectException) {
51+
$this->expectException(
52+
MappingException::class,
6153
);
6254
}
6355

tests/Tests/ORM/Mapping/ManyToOneAssociationMappingTest.php

Lines changed: 4 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,11 @@
44

55
namespace Doctrine\Tests\ORM\Mapping;
66

7-
use Doctrine\Deprecations\PHPUnit\VerifyDeprecations;
87
use Doctrine\ORM\Mapping\DefaultNamingStrategy;
98
use Doctrine\ORM\Mapping\JoinColumnMapping;
109
use Doctrine\ORM\Mapping\ManyToOneAssociationMapping;
10+
use Doctrine\ORM\Mapping\MappingException;
1111
use PHPUnit\Framework\Attributes\DataProvider;
12-
use PHPUnit\Framework\Attributes\WithoutErrorHandler;
1312
use PHPUnit\Framework\TestCase;
1413

1514
use function assert;
@@ -18,8 +17,6 @@
1817

1918
final class ManyToOneAssociationMappingTest extends TestCase
2019
{
21-
use VerifyDeprecations;
22-
2320
public function testItSurvivesSerialization(): void
2421
{
2522
$mapping = new ManyToOneAssociationMapping(
@@ -44,21 +41,14 @@ public function testItSurvivesSerialization(): void
4441

4542
/** @param array<string, mixed> $mappingArray */
4643
#[DataProvider('mappingsProvider')]
47-
#[WithoutErrorHandler]
4844
public function testNullableDefaults(
49-
bool $expectDeprecation,
45+
bool $expectException,
5046
bool $expectedValue,
5147
array $mappingArray,
5248
): void {
5349
$namingStrategy = new DefaultNamingStrategy();
54-
if ($expectDeprecation) {
55-
$this->expectDeprecationWithIdentifier(
56-
'https://github/doctrine/orm/pull/12125',
57-
);
58-
} else {
59-
$this->expectNoDeprecationWithIdentifier(
60-
'https://github/doctrine/orm/pull/12125',
61-
);
50+
if ($expectException) {
51+
$this->expectException(MappingException::class);
6252
}
6353

6454
$mapping = ManyToOneAssociationMapping::fromMappingArrayAndName(

tests/Tests/ORM/Mapping/MappingDriverTestCase.php

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1132,7 +1132,6 @@ public static function loadMetadata(ClassMetadata $metadata): void
11321132
'name' => 'user_id',
11331133
'referencedColumnName' => 'id',
11341134
'unique' => false,
1135-
'nullable' => false,
11361135
],
11371136
],
11381137
'inverseJoinColumns' =>

tests/Tests/ORM/Mapping/OneToOneOwningSideMappingTest.php

Lines changed: 5 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,11 @@
44

55
namespace Doctrine\Tests\ORM\Mapping;
66

7-
use Doctrine\Deprecations\PHPUnit\VerifyDeprecations;
87
use Doctrine\ORM\Mapping\DefaultNamingStrategy;
98
use Doctrine\ORM\Mapping\JoinColumnMapping;
9+
use Doctrine\ORM\Mapping\MappingException;
1010
use Doctrine\ORM\Mapping\OneToOneOwningSideMapping;
1111
use PHPUnit\Framework\Attributes\DataProvider;
12-
use PHPUnit\Framework\Attributes\WithoutErrorHandler;
1312
use PHPUnit\Framework\TestCase;
1413

1514
use function assert;
@@ -18,8 +17,6 @@
1817

1918
final class OneToOneOwningSideMappingTest extends TestCase
2019
{
21-
use VerifyDeprecations;
22-
2320
public function testItSurvivesSerialization(): void
2421
{
2522
$mapping = new OneToOneOwningSideMapping(
@@ -44,21 +41,15 @@ public function testItSurvivesSerialization(): void
4441

4542
/** @param array<string, mixed> $mappingArray */
4643
#[DataProvider('mappingsProvider')]
47-
#[WithoutErrorHandler]
4844
public function testNullableDefaults(
49-
bool $expectDeprecation,
45+
bool $expectException,
5046
bool $expectedValue,
5147
array $mappingArray,
5248
): void {
5349
$namingStrategy = new DefaultNamingStrategy();
54-
if ($expectDeprecation) {
55-
$this->expectDeprecationWithIdentifier(
56-
'https://github/doctrine/orm/pull/12125',
57-
);
58-
} else {
59-
$this->expectNoDeprecationWithIdentifier(
60-
'https://github/doctrine/orm/pull/12125',
61-
);
50+
51+
if ($expectException) {
52+
$this->expectException(MappingException::class);
6253
}
6354

6455
$mapping = OneToOneOwningSideMapping::fromMappingArrayAndName(

tests/Tests/ORM/Tools/SchemaValidatorTest.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -324,7 +324,7 @@ class DDC1587ValidEntity2
324324
{
325325
#[Id]
326326
#[OneToOne(targetEntity: 'DDC1587ValidEntity1', inversedBy: 'identifier')]
327-
#[JoinColumn(name: 'pk_agent', referencedColumnName: 'pk', nullable: false)]
327+
#[JoinColumn(name: 'pk_agent', referencedColumnName: 'pk')]
328328
private DDC1587ValidEntity1 $agent;
329329

330330
#[Column(name: 'num', type: 'string', length: 16, nullable: true)]

0 commit comments

Comments
 (0)