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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With