I have a really strange case related to doctrine, loggable (DoctrineExtension) and listeners.
I will explain the situation I am having here and below is all the code I think is related to the problem.
I have two entities (Agreement and Template) where an agreement is based on a specific Template version. Template entity has the DoctrineExtension Loggable annotation. So I can revert an Agreement template to the specific version using the LogEntryRepository->revert() method. (I am using a postLoad listener to do that, so each time an agreement is retrieved, the right Template version is loaded for that Agreement).
If I get a controller action where an agreement is retrieved using a ParamConververter annotation, everything works ok and my agreement is retrieved with the right Template. If I try to retrieve the very same agreement in the first line of the controller action using a query builder, I get the following exception
Notice: Trying to get property of non-object in /home/administrator{dir}/vendor/doctrine/orm/lib/Doctrine/ORM/Internal/Hydration/ObjectHydrator.php line 481
Any help would be appreciated. Thanks.
Just copying the parts that are related to the problem:
Entities
/**
* Agreement
*
* @ORM\Table(name="agreement")
* @ORM\Entity
* @Gedmo\Loggable
*/
class Agreement
{
/**
* @var integer
* @ORM\Column(name="id", type="bigint", nullable=false)
* @ORM\Id
* @ORM\GeneratedValue(strategy="IDENTITY")
*/
private $id;
/**
* @var integer
* @ORM\Column(name="template_version", type="bigint", nullable=false)
* @Gedmo\Versioned
*/
private $templateVersion;
/**
* @var \Template
* @ORM\ManyToOne(targetEntity="Template")
* @ORM\JoinColumn(name="template_id", referencedColumnName="id")
*/
private $template;
}
/*
* Template
*
* @ORM\Table(name="template")
* @ORM\Entity
* @ORM\ChangeTrackingPolicy("DEFERRED_EXPLICIT")
* @Gedmo\Loggable
*/
class Template
{
/**
* @var integer
* @ORM\Column(name="id", type="bigint", nullable=false)
* @ORM\Id
* @ORM\GeneratedValue(strategy="IDENTITY")
*/
private $id;
/**
* @var string
* @ORM\Column(name="name", type="string", length=255, nullable=false)
* @Gedmo\Versioned
*/
private $name;
}
Doctrine Subscriber
*(services.yml)*
services:
ourdeal.listener.loggable:
class: App\Bundle\Listener\LoggableSubscriber
tags:
- { name: doctrine.event_subscriber }
class LoggableSubscriber implements EventSubscriber
{
public function getSubscribedEvents()
{
return array(
'prePersist',
'postLoad',
);
}
public function prePersist(LifecycleEventArgs $args)
*...Code omitted...*
public function postLoad(LifecycleEventArgs $args)
{
$entity = $args->getEntity();
$entityManager = $args->getEntityManager();
if ($entity instanceof Agreement)
{
$agreement = $entity;
$repo = $entityManager->getRepository('Gedmo\Loggable\Entity\LogEntry');
$repo->revert($agreement->getTemplate(), $agreement->getTemplateVersion());
}
}
}
Actions
With this action, I get the desired agreement without problems.
/**
* @Route("/agreement/send/{id}", name="agreement/send")
* @ParamConverter("agreement", class="Bundle:Agreement")
* @Template()
*/
public function sendAction(Request $request, Agreement $agreement) {
*...Code omitted...*
}
Using this code, I get the exception (the hardcoded id and this code is just for test)
/**
* @Route("/agreement/send", name="agreement/send")
* @Template()
*/
public function sendAction(Request $request) {
$em = $this->get('doctrine')->getManager();
$qb = $em->createQueryBuilder()->select('a')->from('AppBundle:Agreement', 'a')->where('a.id=1378');
$agreements = $qb->getQuery()->getResult();
}