Miles M.
Miles M.

Reputation: 4169

Why is doctrine always returning null to a left join with condition?

I have a many to many bidirectional association between Event and User entity (User.eventNotified).

I am looking for a function that brings up an event of this association based on its id for a given user.

So my function looks like this:

public function getEventNotifiedById( $user, $eventId )
{
    //We only want to return users nearby who are available OR who
    $qb = $this->getEntityManager()->createQueryBuilder();

    $qb->select( 'USER', 'EVENT' )
        ->from( 'Entity\User',  'USER' )
        ->where(
            $qb->expr()->eq( 'USER', ':user' )
        )
        ->leftJoin( 'USER.eventNotified', 'EVENT', 'WITH', 'EVENT.id = :eventId'  ); //CA NE MARCHE PAS chai pas pq

    $array = array(
         'user'     => $user,
         'eventId'  => $eventId
    );

    $qb->setParameters( $array );

    $user = $qb->getQuery()->getOneOrNullResult();

    if ( $user )
    {
        return $user->getEventNotified();
    }
    else
    {
        return false;
    }
}

But $user->getEventNotified() always return null. Why ?

i guess I am doing something wrong in the left Join but I can't find what. Many Thanks

EDIT:

here are the necessary parts my 2 entities:

USER ENTITY:

<?php

namespace Entity;

use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\ORM\EntityRepository;

require_once 'Repositories/UserRepository.php';

/**
 * User
 *
 * @ORM\Table(name="user")
 * @ORM\Entity(repositoryClass="Repositories\UserRepository")
 */
class User
{
    /**
     * @var integer
     *
     * @ORM\Column(name="id", type="integer", nullable=false, unique=true)
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="IDENTITY")
     */
    private $id;

[...]


    /**
     * Bidirectional - Many users have notified they want to go to different events (OWNING SIDE)
     *
     * @var \Doctrine\Common\Collections\Collection
     *
     * @ORM\ManyToMany(targetEntity="Entity\Event", inversedBy="userNotified", cascade={"persist"})
     */
    private $eventNotified;
[...]
}

EVENT ENTITY

<?php

namespace Entity;

use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\ORM\EntityRepository;

require_once 'Repositories/EventRepository.php';

/**
 * User
 *
 * @ORM\Table(name="event")
 * @ORM\Entity(repositoryClass="Repositories\EventRepository")
 */
class Event
{
    /**
     * @var integer
     *
     * @ORM\Column(name="id", type="integer", nullable=false, unique=false)
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="IDENTITY")
     */
    private $id;
[...]


    /**
     * Bidirectional - Many users are intending many events (INVERSE SIDE)
     *
     * @ORM\ManyToMany(targetEntity="User", mappedBy="eventNotified", cascade={"remove"})
     */
    private $userNotified;
[...]
}

Honestly, I'm using this association a lot in my repo and everything works just fine. I have tried to var dump my user and see his events notified without the "with" clause in the left join and I can see my event there.

Many thanks for your help

Upvotes: 2

Views: 1639

Answers (2)

Tim Lieberman
Tim Lieberman

Reputation: 571

[UPDATED]

First of all you should get rid of the require_once and the use Doctrine\ORM\EntityRepository; You're setting the repository class in annotation and shouldn't ever be using any repository from a entity. Also why in your Event class are you using, unique=false with an id? You also need the

@ORM\JoinTable(name="user_event")

for manyToMany

So ASSUMING you are in fact setting the eventNotified as an ArrayCollection in the constructor and also have your getter and setters there which I pretty sure you do. I would say check the your setter and make sure you're setting

$this->eventNotified[] = $eventNotified;
return $this;

And that in your getter you're actually returning

$this->eventNotified;

If that's all good and I understand this right it seems like your query is wrong anyway. Your join needs to be before the where.

$event = $qb->select( 'event' )
    ->from( 'Entity\event',  'event' )
    ->leftJoin( 'event.userNotified', 'user', 'WITH', 'user.id = :userId'  );
    ->where('event.id = :eventId')
    ->setParameters(['userId' => $user->getId(), 'eventId' => $eventId])
    ->getQuery()
    ->getOneOrNullResult();

 return $event ? $event : false;

Upvotes: 2

SBH
SBH

Reputation: 1918

Your Many-To-Many relation is not correct defined, you have to specify in which additional cross table you want to store the relations on the owning site. Have a look at the Doctrine documentation.

class User
{
    // ...

    /**
     * Bidirectional - Many users have notified they want to go to different events (OWNING SIDE)
     *
     * @var \Doctrine\Common\Collections\Collection
     *
     * @ORM\ManyToMany(targetEntity="Entity\Event", inversedBy="userNotified", cascade={"persist"})
     * @ORM\JoinTable(name="user_event")
     */
    private $eventNotified;

    // ...
}

Upvotes: 0

Related Questions