Let's say I have an Doctrine's (version 2) entity as follows:
<?php
namespace AppBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* User
*
* @ORM\Table(name="users")
* @ORM\Entity
*/
class User {
/**
* @var integer
*
* @ORM\Column(name="id", type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="IDENTITY")
*/
private $id
/**
* @var string
*
* @ORM\Column(name="name", type="string", length=50, nullable=false)
*/
private $name;
/**
* @var string
*
* @ORM\Column(name="group_id", type="string", length=6, nullable=true)
*/
private $groupId;
// Getters and setters...
}
Now, I would like to manage User
's relation to Group
, but with some conditions, like:
NULL
(or some sort of skeleton/template of \AppBundle\Entity\Group
with fixed values not loaded from database) if Group
of users.group_id
does not exist, even if it is set to a value (no key restrictions set in the database to prevent this behaviour), so some sort of validation/check requiredGroup
, when calling $user->getGroup()
I am reading Google on and on and I'm confused of how to achieve that properly (in the line with Doctrine/Symfony way).
I could add a ManyToOne to the entity's class relation like this:
/**
* @var \AppBundle\Entity\Group
*
* @ORM\ManyToOne(targetEntity="AppBundle\Entity\Group")
* @ORM\JoinColumns({
* @ORM\JoinColumn(name="group_id", referencedColumnName="id")
* })
*/
private $group;
But then how to prevent exceptions caused by non-existing foreign keys? I.e. I would like to retrieve user's group details when it is available in my database, but when it is not I do not want Doctrine to throw an exception an crash my application.
People say that using an Entity Manager from within an Entity
is a very bad practice and I agree. But I am confused about using Proxy Objects or Inheritance Mapping for this purposes.
It seems like using Models
could be the way, but I couldn't find any strong documentation of how to properly implement them in Doctrine2.
Please help if you can. In Kohana it was so, so simple (but immature this way).
EDIT:
@Massimiliano Fedel suggested trying catching an exception in User::getGroup()
method, to eventually make non-existed groups return as NULL
.
So I have commited this code:
/**
* Get group
*
* @return \AppBundle\Entity\Group
*/
public function getGroup() {
try {
$group = $this->group;
} catch (\Doctrine\ORM\EntityNotFoundException $e) {
$group = null;
}
return $group;
}
Unfortunatelly, it seems that exception cannot be catched this way, because framework exits with an Doctrine\ORM\EntityNotFoundException
:
Entity of type 'AppBundle\Entity\Group' for IDs id(999) was not found
EDIT 2:
Below you can find some basing schema of User
flow, i.e. why I can not ensure that all Users
will have available Groups
in my database.
1)Have you tried catching the exception inside the getter method of the "group"? so that you can catch the exception and return "null" in case an exception occured.
2) as from the doctrine 2.1 documentation: "Associations are marked as Lazy by default, which means the whole collection object for an association is populated the first time its accessed." http://doctrine-orm.readthedocs.org/projects/doctrine-orm/en/latest/tutorials/extra-lazy-associations.html
Well, what about creating a service, that is going to wrap your CRUD operations on the User
entity, let's say UserService
? This way, you can leave group_id
as it is and add group
field that is not managed (no annotations, not persisted to DB).
The UserService
will have getGroup
method, that will take User
as an argument, then retrieve his group_id
and use EntityManager
(or indeed GroupService
) to fetch the Group
entity, if none was found, you will return null
, otherwise you will set the returned Group
to the unmanaged field of the entity, so you don't have to fetch it again next time.
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