I have two classes linked with a one-to-one relation.
class Client { ... /** * @ORM\OneToOne(targetEntity="ClientInfo") * @ORM\JoinColumn(name="id", referencedColumnName="client_id") */ private $info; ... public function doSomething() { if (!$this->getInfo() instanceof ClientInfo) { return false; } return $this->getInfo()->doSomething(); } ... } class ClientInfo { ... /** * @ORM\Id * @ORM\OneToOne(targetEntity="Client") * @ORM\JoinColumn(name="client_id", referencedColumnName="id") */ private $client; ... public function doSomething() { return 'something'; } ... }
Those classes are loaded with database content with Doctrine. It is working perfectly when there is data in the database. But if there is not ClientInfo data, I have a \Doctrine\ORM\EntityNotFoundException raised.
So I changed the doSomething() method to take this into account.
public function doSomething() { if (!$this->getInfo() instanceof ClientInfo) { return false; } try { return $this->getInfo()->doSomething(); } catch (\Doctrine\ORM\EntityNotFoundException $e) { return false; } }
But it does not feel right to me since it is tied with Doctrine. I am trying to modify my unit tests to add a mock of the proxy object but it does not feel right either.
Is there a better way of doing that?
EDIT 1
I followed Nico Kaag suggestion but it does not change anything.
My constructor in my Client class look like this:
public function __construct() { $this->info = new ClientInfo(); }
If I do a var_dump
of $this→info after retrieving my object with Doctrine, this is what I get.
object(Proxies\__CG__\MyBundle\Entity\ClientInfo)[444] public '__initializer__' => object(Closure)[461] public '__cloner__' => object(Closure)[462] public '__isInitialized__' => boolean false private 'client' (MyBundle\Entity\ClientInfo) => string '21055' (length=5) ...
EDIT 2
I finally changed what I have done. I removed the try..catch block and change the query to retrieve objects from database. Now I force the query to retrieve the ClientInfo object at the same time as the Client object.
This way, I can trust my test and if I forget to query both objects simultaneously, I will have an exception to remind it to me.
See I have made classes for you.
use Doctrine\ORM\Mapping AS ORM; /** * @ORM\Entity */ class client { /** * @ORM\Id * @ORM\Column(type="integer") * @ORM\GeneratedValue(strategy="AUTO") */ private $id; /** * @ORM\OneToOne(targetEntity="Entities\client_info", inversedBy="client") * @ORM\JoinColumn(name="client_info_id", referencedColumnName="id", unique=true) */ private $clientInfo; }
use Doctrine\ORM\Mapping AS ORM; /** * @ORM\Entity */ class client_info { /** * @ORM\Id * @ORM\Column(type="integer") * @ORM\GeneratedValue(strategy="AUTO") */ private $id; /** * @ORM\OneToOne(targetEntity="Entities\client", mappedBy="clientInfo") */ private $client; }
Try this, you will not get such issue.
Also I have used bi-directional relation with cardinality one-to-one, parent connection 0:1*- (parent optional), please see the diagram.
Suggetion : Use ORM designer tool for designing and extracting entity classes.