0

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();
    }

2 Answers2

0

use setParameter()

$em->createQueryBuilder()
    ->select('a')
    ->from('AppBundle:Agreement', 'a')
    ->where('a.id = :id')
    ->setParameter('id', $request->get('id'));
Nicolai Fröhlich
  • 51,330
  • 11
  • 126
  • 130
  • Thanks for you answer, but this does not solve the problem. I have checked the sql query executed and it is correct. I think the problem is when trying to map the entity object. – Sergio Romano Jun 27 '13 at 11:47
0

There is a known bug #52083 that affects PHP versions before 5.3.4, which fails randomly with "Notice: Trying to get property of non-object".

If that is your case, try upgrading PHP will solve your issue. Hope that helps

Arsham
  • 1,432
  • 3
  • 19
  • 28