TD;LR you can't use the doctrine entity manager after a rollback happened. To do that, use doctrine managerRegistry
to reset the entityManager
Handling errors is an important part of engineering.
Working with Doctrine ORM usually make our life way simpler but when it comes to doing things after a database error, things tends to complicate.
Let's say we want to save something but keep a trace if we encounter and error :
<?php
$something = new Something();
try {
$this->entityManager->persist($something);
$this->entityManager->flush();
} catch (\Throwable $exception) {
$something->isErroneous();
$something->setErrorMessage($exception->getMessage());
$this->entityManager->flush();
}
If we encounter a SQL error raised by our database, the following exception will appear :
In EntityManagerClosed.php line 11:
The EntityManager is closed.
You might think "Why the F is my entity manager closed ?".
Well, doctrine automatically closes it on error :
// Doctrine\ORM\UnitOfWork.php:
} catch (Throwable $e) {
$this->em->close();
if ($conn->isTransactionActive()) {
$conn->rollBack();
}
$this->afterTransactionRolledBack();
throw $e;
}
In order to properly do that, we will leverage the Doctrine\Persistence\ManagerRegistry
with the transactional system :
<?php
$something = new Something();
$this->entityManager->beginTransaction();
try {
$this->entityManager->persist($something);
$this->entityManager->flush();
$this->entityManager->commit();
} catch (\Throwable $exception) {
$this->entityManager->rollback();
$this->managerRegistry->resetManager();
$something->isErroneous();
$something->setErrorMessage($exception->getMessage());
$this->entityManager->persist($something);
$this->entityManager->flush();
$this->entityManager->commit();
}
Problem solved ¯_(ツ)_/¯
Top comments (0)