I am importing users from an excel file. I have created entity manager:
$em = $this->getDoctrine()->getManager();
This is my loop:
...
for ($i=2; $i<=count($usersdatas); $i++) { // $userdatas: an array of users imported from excel
$nuser = new User();
$nuser->setEmail($usersdatas[$i]['A']); // email is unique in db
$nuser->setFname($usersdatas[$i]['B']);
$nuser->setLname($usersdatas[$i]['C']);
$nuser->addChannel($channel); //ManytoMany relation
$em->persist($nuser);
$em->flush();
}
...
- Email field is unique in db and I do not want to check duplicate before flush (db validation)
- I want to flush one by one for log reasons (not batch insert).
- All my other codes and files (entity, services, configurations, ...) are correct and has no errors.
The first problem is if one of the rows has an email that exist in db (duplicate), the loop breaks by an exception from db. I have solved the problem with this simple change:
...
try {
$em->persist($nuser);
$em->flush();
} catch (\Exception $e) {
...
}
...
The next problem is the "The EntityManager is closed" exception. If one email is duplicate, EntityManager ($em) will close automatically. I have solved this by creating the $em before try/catch:
...
if (!$em->isOpen()) {
$em = $em->create(
$em->getConnection(), $em->getConfiguration());
}
...
Everything is OK. But I have a big problem with adding the channel to user:
...
$nuser->addChannel($channel); //ManytoMany relation
...
$channel is not a new one. But after closing and creating the EntityManager, the system thinks it is new on line persist (The $channel will successfully add if there is no errors):
ORMInvalidArgumentException {#1400 ▼
#message: "A new entity was found through the relationship 'My\UserBundle\Entity\User#channels' that was not configured to cascade persist operations for entity: My\PostBundle\Entity\Channel@000000002768057d0000000046371762. 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 'My\PostBundle\Entity\Channel#__toString()' to get a clue."
#code: 0
#file: "...\vendor\doctrine\orm\lib\Doctrine\ORM\ORMInvalidArgumentException.php"
#line: 91
-trace: array:13 [▶]
}
All my problems are from recreating EntityManager. I think its a bug. Validating data in database side (Unique, Null, Foreign Keys, ...) is common. Closing the EntityManager after db errors means we can not communicate with db after any error.
I have 2 questions:
- Is there any way to prevent EntityManager close?!
- Can I use DBAL Doctrine to import my users? (users may have duplicated emails)