Doctrine mapped field is not working

2019-06-04 20:16发布

问题:

I have two entities User\User and Misc\Notification and I want to have the possibility to fetch the user's notifications inside the User entity, by doing $user->getNotifications(). Usually I have no problem with this type of relations.

See my code below (I just added the TicketApp relation as an example, since this relation works and is exactly the same):

User\User : properties

/**
 * This is working
 * @ORM\OneToMany(targetEntity="[...]\Entity\Ticket\TicketApp", mappedBy="author")
 */
private $tickets;

/**
 * This is not
 * @ORM\OneToMany(targetEntity="[...]\Entity\Misc\Notification", mappedBy="receiver", fetch="EXTRA_LAZY")
 */
private $notifications;

User\User : __construct()

$this->tickets       = new \Doctrine\Common\Collections\ArrayCollection();
$this->notifications = new \Doctrine\Common\Collections\ArrayCollection();

Misc\Notification : properties

/**
 * @ORM\ManyToOne(targetEntity="[...]\Entity\User\User", inversedBy="notifications")
 * @ORM\JoinColumn(nullable=false)
 */
private $receiver;

This seems to be Ok (or maybe this evening I'm completely blind...). The problem is : $user->getNotifications() returns null instead of a Doctrine Collection object. I have datas in my table. This type of code works and returns two notifications:

$em->getRepository('[...]:Misc\Notification')->findByReceiver($user);

Also, I noticed in the Symfony debug toolbar that no query is fired when using $user->getNotifications().

回答1:

I was despairing of finding a solution when I remembered that Doctrine have its proper cache, independent from Symfony (I tried tens of cache:clear without any change). I thought that my problem could be a Doctrine cache issue, so I tried to clear the cache:

app/console doctrine:cache:clear-metadata

(If you are using Doctrine standalone, this command has its equivalent in pure Doctrine, Symfony just renames and improves Doctrine commands).

If you have a normal installation, this should work, otherwise continue to read.

In a normal time, in dev mode at least, Doctrine regenerates the metadata cache at each request. But Doctrine also have an APC interface to store its cache... I activated it two or three weeks ago, and I have completely forgotten it. When I ran the command above, Doctrine said:

Cannot clear APC Cache from Console, its shared in the Webserver memory and not accessible from the CLI.

The problem is clear now. Doctrine fills the cache and then can't remove data correctly. The getNotifications method was returning null because it was pure PHP, but Doctrine had no knowledge that the notifications property was SQL-mapped. So the field were never initialized. If you use another cacher, that's probably a similar issue.

The error given above is self-explaining. You'll need to clear the APC datastore. Since it is hosted by the webserver process, just reboot this guy:

sudo service apache2 restart

Amen.



标签: php doctrine