Skip to content

Commit 03783f8

Browse files
authored
Merge pull request #12536 from JamBalaya56562/agent/validate-sole-many-to-one-identifier
Validate ManyToOne associations used as sole identifiers
2 parents d753691 + c6935cc commit 03783f8

2 files changed

Lines changed: 37 additions & 0 deletions

File tree

src/Tools/SchemaValidator.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,11 @@ public function validateClass(ClassMetadata $class): array
135135
return $ce;
136136
}
137137

138+
if ($assoc->isManyToOne() && count($class->identifier) === 1 && $class->identifier[0] === $fieldName) {
139+
$ce[] = "The association '" . $class->name . '#' . $fieldName . "' is a many-to-one association and is the sole identifier of the entity. " .
140+
'This effectively makes the association one-to-one; use a one-to-one association instead or add another identifier field.';
141+
}
142+
138143
if (isset($assoc->id) && $targetMetadata->containsForeignIdentifier) {
139144
$ce[] = "Cannot map association '" . $class->name . '#' . $fieldName . ' as identifier, because ' .
140145
"the target entity '" . $targetMetadata->name . "' also maps an association as identifier.";

tests/Tests/ORM/Tools/SchemaValidatorTest.php

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,25 @@ public function testValidOneToOneAsIdentifierSchema(): void
111111
self::assertEquals([], $ce);
112112
}
113113

114+
public function testInvalidManyToOneAsSoleIdentifier(): void
115+
{
116+
$class = $this->em->getClassMetadata(DDC1649Two::class);
117+
$ce = $this->validator->validateClass($class);
118+
119+
self::assertEquals(
120+
["The association 'Doctrine\Tests\ORM\Tools\DDC1649Two#one' is a many-to-one association and is the sole identifier of the entity. This effectively makes the association one-to-one; use a one-to-one association instead or add another identifier field."],
121+
$ce,
122+
);
123+
}
124+
125+
public function testValidManyToOneAsPartOfCompositeIdentifier(): void
126+
{
127+
$class = $this->em->getClassMetadata(ValidCompositeIdentifier::class);
128+
$ce = $this->validator->validateClass($class);
129+
130+
self::assertEquals([], $ce);
131+
}
132+
114133
#[Group('DDC-1649')]
115134
public function testInvalidTripleAssociationAsKeyMapping(): void
116135
{
@@ -119,6 +138,7 @@ public function testInvalidTripleAssociationAsKeyMapping(): void
119138

120139
self::assertEquals(
121140
[
141+
"The association 'Doctrine\Tests\ORM\Tools\DDC1649Three#two' is a many-to-one association and is the sole identifier of the entity. This effectively makes the association one-to-one; use a one-to-one association instead or add another identifier field.",
122142
"Cannot map association 'Doctrine\Tests\ORM\Tools\DDC1649Three#two as identifier, because the target entity 'Doctrine\Tests\ORM\Tools\DDC1649Two' also maps an association as identifier.",
123143
"The referenced column name 'id' has to be a primary key column on the target entity class 'Doctrine\Tests\ORM\Tools\DDC1649Two'.",
124144
],
@@ -366,6 +386,18 @@ class DDC1649Two
366386
public $one;
367387
}
368388

389+
#[Entity]
390+
class ValidCompositeIdentifier
391+
{
392+
#[Id]
393+
#[Column]
394+
public int $id;
395+
396+
#[Id]
397+
#[ManyToOne(targetEntity: 'DDC1649One')]
398+
public DDC1649One $one;
399+
}
400+
369401
#[Entity]
370402
class DDC1649Three
371403
{

0 commit comments

Comments
 (0)