Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Getting only ID from entity relations without fetching whole object in Doctrine

Assume I've an entity, which references itself to map parent-child-relations

class Food
{
    /**
     * @ORM\Id
     * @ORM\Column(type="integer")
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    protected $id;

    /**
     * @ORM\ManyToOne(targetEntity="Food", inversedBy="foodChildren")
     * @ORM\JoinColumn(name="food_group_id", nullable=true)
     */
    protected $foodGroup;

    /**
     * @ORM\OneToMany(targetEntity="Food", mappedBy="foodGroup", fetch="LAZY", cascade={"remove"})
     */
    protected $foodChildren;

I have a use case where I want to get food_group_id of an entity without getting full parent object from database. Using fetch="LAZY" doesn't keep Doctrine from querying again. Is there a way to return only the ID when getting $food->getFoodGroup()?

like image 923
rabudde Avatar asked Oct 02 '13 14:10

rabudde


3 Answers

Don't complicate your life, you can just do

$food->getFoodGroup()->getId()

This WILL NOT perform any additional query or trigger lazy load!

This is because your $food->foodGroup is a proxy object which knows about it's ID. It will only do lazy load if you call a getter method of some field which hasn't been loaded.

like image 122
Igor Pantović Avatar answered Oct 19 '22 18:10

Igor Pantović


You should be able to define the ID field, associate it with the ORM, and then create the getter for that field, and it should work.

/**
 * @ORM\ManyToOne(targetEntity="Food", inversedBy="foodChildren")
 * @ORM\JoinColumn(name="foodGroupId", referencedColumnName="id")
 */
protected $foodGroup;

/**
 * @ORM\Column(type="integer")
 */
protected $foodGroupId;

public function getFoodGroupId() {
    return $this->foodGroupId;
}

Note, I changed the field name in my example to Pascal Case, for consistency. Also, I'm new to Symfony, but your ManyToOne association mapping seems odd. I'm not sure why you have nullable on the entity (I just haven't seen that before). You don't have a referencedColumnName="id", but maybe that is just because it defaults to "id" (I like to be explicit). See Doctrine docs.

I had a very similar problem, which was caused just because I hadn't associated that field with the ORM. So you should know that it IS possible to call:

$food = $em->getRepository("AcmeFoodBundle:Food")->find($id);
$food->getFoodGroupId();
like image 34
Chadwick Meyer Avatar answered Oct 19 '22 17:10

Chadwick Meyer


You can use

$em->getUnitOfWork()->getEntityIdentifier(...);

to get id's without making joins.

In your example it would be something like this:

$em = $this->getDoctrine()->getManager();
$food = $em->getRepository('HungryHungryBundle:Food')->findOneById($id);
print_r($em->getUnitOfWork()->getEntityIdentifier($food->getFoodGroup())); 
die();

This way you will get the food_group_id without making an extra join.

like image 4
Noquepoaqui Avatar answered Oct 19 '22 17:10

Noquepoaqui