-1

I would like to understand why my DQL request doesn't work. I've to entity : books(ouvrages) and authors(auteurs), there is many to many relation, so in my database a join table is create books_authors (ouvrages_auteurs) with reference "id" of each other. I would like to use this join table for have all informations of my two entity books and authors.

I've make many request in my BooksRepository but it's doesn't work :

public function getOuvrageTradeByAuteur(array $autor){
    $query = $this->getEntityManager()->createQuery("SELECT o,a FROM SBMainBundle:Ouvrages o JOIN ouvrages_auteurs oa JOIN SBMainBundle:Auteurs a WHERE o.is_trade = true  AND o.id = oa.ouvrages_id AND oa.auteurs_id = a.id AND a.nom_auteur = :autor")
                    ->setParameter('autor',$autor);
    return $query->getResult();
}

public function getBooksTradeByAutor(array $autor){
    //requete DQL pour un many to many
    $query = $this->createQueryBuilder('o');
    $query->join('o.auteur','auteurs')
            ->where($query->expr()->in('auteurs.nomAuteur',$autor))
            ->andWhere('o.isTrade = true')
            ->orderBy('o.id','desc')
            ->addSelect('o,auteurs');
    return $query->getQuery()->getResult();
}

public function getBooksSellByAutor(array $autor){
    //requete DQL pour un many to many
    $query = $this->createQueryBuilder('o');
    $query->join('o.auteur','auteurs')
        ->where($query->expr()->in('auteurs.nomAuteur',$autor))
        ->andWhere('o.isSell = true')
        ->orderBy('o.id','desc')
        ->addSelect('o,auteurs');
    return $query->getQuery()->getResult();
}

public function getOuvragesEchangesByAutor($auteurs){
    //requete en DQL 2eme partie
    $query = $this->createQueryBuilder('o')->where('o.auteur = :autor')
                                            ->andWhere('o.isTrade = true')
                                            ->join('o.auteur','a')
                                            ->setParameter('autor',$auteurs)
                                            ->orderBy('o.id','desc')
                                            ->addSelect('a');
    return $query->getQuery()->getResult();
}

public function getOuvragesVentesByAutor($auteurs){
    //requete en DQL 2eme partie
    $query = $this->createQueryBuilder('o')->where('o.auteur = :autor')
                                            ->andWhere('o.isSell = true')
                                            ->join('o.auteur','a')
                                            ->setParameter('autor',$auteurs)
                                            ->orderBy('o.id','desc')
                                            ->addSelect('a');
    return $query->getQuery()->getResult();
}

Edit for error message :

[Semantical Error] line 0, col 45 near 'ouvrages_auteurs': Error: Class 'ouvrages_auteurs' is not defined.

500 Internal Server Error - QueryException 1 linked Exception: QueryException »

[2/2] QueryException: [Semantical Error] line 0, col 45 near 'ouvrages_auteurs': Error: Class 'ouvrages_auteurs' is not defined.

[1/2] QueryException: SELECT o,a FROM SBMainBundle:Ouvrages o JOIN ouvrages_auteurs oa JOIN SBMainBundle:Auteurs a WHERE o.is_trade = true AND o.id = oa.ouvrages_id AND oa.auteurs_id = a.id AND a.nom_auteur = :autor

Edit for the Nnew issue :

[Semantical Error] line 0, col 79 near 'auteur = :autor': Error: Invalid PathExpression. StateFieldPathExpression or SingleValuedAssociationField expected.

500 Internal Server Error - QueryException 1 linked Exception: QueryException »

[2/2] QueryException: [Semantical Error] line 0, col 79 near 'auteur = :autor': Error: Invalid PathExpression. StateFieldPathExpression or SingleValuedAssociationField expected.

[1/2] QueryException: SELECT o, a FROM SB\MainBundle\Entity\Ouvrages o INNER JOIN o.auteur a WHERE o.auteur = :autor AND o.isSell = true ORDER BY o.id desc

I've use this request :

    public function getOuvragesEchangesByAutor($auteurs){
    //requete en DQL 2eme partie
    $query = $this->createQueryBuilder('o')->where('o.auteur = :autor')
                                            ->andWhere('o.isTrade = true')
                                            ->join('o.auteur','a')
                                            ->setParameter('autor',$auteurs)
                                            ->orderBy('o.id','desc')
                                            ->addSelect('a');
    return $query->getQuery()->getResult();
}

Thanks for your help ! :D

Tirkal
  • 43
  • 8
  • 1
    What of your 4 queries doesn't work?. Can you share the error message you get? – Hokusai Apr 04 '17 at 19:26
  • 1
    Is there a reason for coding all of these queries yourself? If you have a ManyToMany relationship defined in your entities when symfony/doctrine can do all of this heavy lifting for you and with MUCH less code. – ehymel Apr 05 '17 at 04:11
  • @ehymel: I try to find the good query to get all informations I need, here books and authors informations. There is why I've many queries. How I can do make the good query for a ManyToMany ? – Tirkal Apr 05 '17 at 12:04
  • @Hokusai : I had the error message I've when I use the first query. – Tirkal Apr 05 '17 at 12:06

1 Answers1

0

That error informs that the problem probably is in your entity definition. ouvrages_auteurs must exist like an association property in your Ouvrages entity, but it is more simple call it as auteurs like this:

 // Ouvrage Entity definitions...

 /**
 * @ORM\ManyToMany(targetEntity="Auteurs", inversedBy="ouvrages")
 * @ORM\JoinTable(name="ouvrages_auteurs",
 *      joinColumns={@ORM\JoinColumn(name="ouvrage_id", referencedColumnName="id")},
 *      inverseJoinColumns={@ORM\JoinColumn(name="auteur_id", referencedColumnName="id")}
 *      )
 */
private $auteurs;

/*
 * Constructor
 */
public function __construct()
{
    $this->auteurs =  new \Doctrine\Common\Collections\ArrayCollection();
}

Later in your query you should create dql JOIN clauses like this type:

SELECT o, a
FROM SBMainBundle:Ouvrages o 
JOIN o.auteurs a 
WHERE o.is_trade = true  

all related auteurs with selected ouvrages will be returned in result, clause: o.id = oa.ouvrages_id is not necessary.

More info about Doctrine mapping here: http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/reference/association-mapping.html#many-to-many-unidirectional

EDIT for new issue:

I think problem is that if autors info are in auteurs then:

$query = $this->createQueryBuilder('o')->where('a.id = :autor')
                                        ->andWhere('o.isTrade = true')
                                        ->join('o.auteur','a')
                                        ->setParameter('autor',$auteurs)
                                        ->orderBy('o.id','desc')
                                        ->addSelect('a');
Hokusai
  • 2,219
  • 1
  • 21
  • 22
  • Thanks, it's helping me ! But now I've a new one. I've made an edit for this new issue. – Tirkal Apr 06 '17 at 11:21
  • Thanks for the edit, it's really helping ! But when I send a request for looking for an autor and find all books with his name, I fond no one. I know I've books of the autor I looking for in my databse. When I make a var_dump to my request, I see a string not an array : `{ ["name":"Doctrine\ORM\Query\Parameter":private]=> string(5) "autor" ["value":"Doctrine\ORM\Query\Parameter":private]=> object(SB\MainBundle\Entity\Auteurs)#389 (2) { ["id":"SB\MainBundle\Entity\Auteurs":private]=> int(19) ["nomAuteur":"SB\MainBundle\Entity\Auteurs":private]=> string(12) "Issac Asimov" }`. What can I do ? – Tirkal Apr 07 '17 at 16:03
  • You can't help my for this new issue ? – Tirkal Apr 10 '17 at 16:10
  • Thanks ! It's all good ! I try the query and it's works !!! Thanks you so much Hokusai !!! – Tirkal Apr 14 '17 at 12:38