Answer the question
In order to leave comments, you need to log in
Why does a unique index throw an error on a cascading operation?
email mapping
<unique-constraints>
<unique-constraint columns="user_uuid,is_active,is_fallback" name="unique_user_active_email"/>
</unique-constraints>
...
<many-to-one target-entity="App\Domain\UserPack\User\Entity\User"
field="user"
inversed-by="emails"
>
<cascade>
<cascade-persist/>
</cascade>
<join-column name="user_uuid" referenced-column-name="uuid"/>
</many-to-one>
<one-to-many target-entity="App\Domain\UserPack\Email\Entity\UserEmail"
mapped-by="user"
field="emails"
index-by="email.email"
orphan-removal="true"
>
<cascade>
<cascade-persist/>
<cascade-remove/>
</cascade>
<order-by>
<order-by-field name="createdAt" direction="DESC"/>
</order-by>
</one-to-many>
UPDATE user_email SET updated_at = '2021-05-30 10:30:41', is_active = false, is_fallback = false WHERE uuid = 'c2c54260-c130-11eb-8a5b-004e01bcde28';
EXCEPTION /.../vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/AbstractSQLiteDriver.php.
Message: An exception occurred while executing
'UPDATE user_email SET updated_at = ?, is_active = ? WHERE uuid = ?'
with params ["2021-05-30 10:48:01", 0, "7ebf86ee-c134-11eb-911b-004e01bcde28"]:
SQLSTATE[23000]: Integrity constraint violation: 19
UNIQUE constraint failed: user_email.user_uuid, user_email.is_active. Code: 0 [] []
$this->emails[$keyEmail] = $email;
EXCEPTION /...vendor/symfony/doctrine-bridge/Messenger/DoctrineTransactionMiddleware.php.
Message: An exception occurred while executing
'NSERT INTO user_email (created_at, updated_at, uuid, email, is_fallback, is_active, user_uuid) VALUES (?, ?, ?, ?, ?, ?, ?)' with
params ["2021-05-30 11:04:58", "2021-05-30 11:04:58", "df5ada06-c136-11eb-b113-004e01bcde28", "[email protected]",
0, 1, "de1204bc-c136-11eb-95d7-004e01bcde28"]:
SQLSTATE[23000]: Integrity constraint violation: 19 UNIQUE constraint failed: user_email.user_uuid, user_email.is_active, user_email.is_fallback. Code: 0 [] []
A new entity was found through the relationship 'App\Domain\UserPack\User\Entity\User#emails' that was not
configured to cascade persist operations for entity:
App\Domain\UserPack\Email\Entity\[email protected] To solve this issue: Either explicitly
call EntityManager#persist() on this unknown entity or configure cascade persist this association in the mapping for example
@ManyToOne(..,cascade={"persist"}). If you cannot find out which entity causes the problem implement
'App\Domain\UserPack\Email\Entity\UserEmail#__toString()' to get a clue.
Answer the question
In order to leave comments, you need to log in
The thing is that when adding a new email, there is a filter and turning off the old ones.
public function disableOldEmails(bool $isFallbackEmailToDisable = false): void {
$updateDto = new UserEmailUpdateDTO(false);
$this->emails->map(
static function (UserEmail $relatedEmail) use ($isFallbackEmailToDisable, $updateDto) {
if ($isFallbackEmailToDisable === $relatedEmail->isFallback()->value()) {
$relatedEmail->update($updateDto);
}
}
);
}
<one-to-many target-entity="App\Domain\UserPack\Email\Entity\UserEmail"
mapped-by="user"
field="emails"
index-by="email.email"
orphan-removal="true"
>
<cascade>
<cascade-persist/> ////// <---
<cascade-remove/>
</cascade>
...
$entity->disableOldEmails(); // ранее метод был приватным
foreach ($entity->emails() as $email) {
$this->userEmailRepository->save($email); // мануально персистим и сразу делаем флаш, коммит
}
Didn't find what you were looking for?
Ask your questionAsk a Question
731 491 924 answers to any question