In my app, when users sign up I have to send them an email with a validation key, as usually happens on most websites, I'm trying to do this with Doctrine but I can’t get it to work when I try to persist()
the user.
First of all, I think the correct way in this case is to use a OneToOne unidirectional relationship, but I don’t know if it would be better to use a bidirectional one. I've tried both and I always get an error.
I have read these two questions carefully:
One to one relationship on two tables sharing primary key
Doctrine one-to-one unidirectional
As well as this part of the documentation. When I validate the schema (php bin/console doctrine:schema:validate
) everything is fine.
class Usuario {
/**
* @ORM\Column(name="id", type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="IDENTITY")
*/
private $id;
// ...
}
class ClaveVal {
/**
* @ORM\Id
* @ORM\OneToOne(targetEntity="Usuario")
*/
private $usuario;
/**
* @ORM\Column(name="clave", type="string", length=20, nullable=false)
* @Assert\NotBlank()
*/
private $clave;
// ...
}
Which is quite similar to this.
Now, I'm trying to persist()
a new Usuario and a new ClaveVal for this usuario like this:
$usuario = new Usuario();
// Add usuario attributes
$claveVal = new ClaveVal();
$claveVal->setUsuario($usuario);
$claveVal->setClave(‘123456’);
$em->persist($usuario);
$em->persist($claveVal);
But I get this error:
The given entity of type 'AppBundle\Entity\ClaveVal' (AppBundle\Entity\ClaveVal@000000007020f28f0000000031d5c8c6) has no identity/no id values set. It cannot be added to the identity map
I know why this happens. This works perfectly:
$em->persist($usuario);
$em->flush();
$em->persist($claveVal);
$em->flush();
But I don't want to do that because I want it to be a unit of work
using flush()
only once.
Besides, as the author of the post I linked above says, it should be Doctrine's job to flush()
at the right moment to get the id.
So, how can I achieve this using flush()
only once (and without using transactions or listeners, I'm sure there is an easier way to do this)? Would it be better to use a bidirectional OneToOne relationship? As I said, I tried it too but I got the same error.
Thanks in advance.