Bonjour,

Il y a une chose que j'ai pas compris sous symfony 2 avec les entity et doctrine

Admettons que je doit réaliser cette requête :

SELECT livre.code_ean, livre.idlivre
FROM eleve,livre,classe,eleve_has_options,classe_has_options,options
WHERE eleve.classe_idclasse=classe.idclasse
AND eleve_has_options.eleve_ideleve=eleve.ideleve
AND eleve_has_options.options_idoption=options.idoption
AND classe_has_options.classe_idclasse=eleve.classe_idclasse 
AND classe_has_options.options_idoption=eleve_has_options.options_idoption
AND classe_has_options.livre_idlivre=livre.idlivre
And eleve.ideleve=5

Avec Symfony 2 et les entity comment accéder à cette colonne eleve_has_options.eleve_ideleve et eleve_has_options.options_idoption
sachant que ces colonne sont dans l'entity Eleve

Entity Eleve :

<?php
namespace LGB\BourseLivresBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;
/**
 * LGB\BourseLivresBundle\Entity\Eleve
 *
 * @ORM\Table(name="eleve")
 * @ORM\Entity(repositoryClass="LGB\BourseLivresBundle\Entity\EleveRepository")
 */
class Eleve
{
    /**
     * @var integer $ideleve
     *
     * @ORM\Column(name="ideleve", type="integer", nullable=false)
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="IDENTITY")
     */
    private $ideleve;
    /**
     * @var string $nom
     *
     * @ORM\Column(name="nom", type="string", length=30, nullable=false)
     */
    private $nom;
    /**
     * @var string $prenom
     * 
     * @ORM\Column(name="prenom", type="string", length=30, nullable=false)
     */
    private $prenom;
    /**
     * @var date $dateNaissance
     * 
     * @ORM\Column(name="date_naissance", type="date", nullable=false)
     */
    private $dateNaissance;
    /**
     * @var Options
     *
     * @ORM\ManyToMany(targetEntity="Options", inversedBy="eleveeleve")
     * @ORM\JoinTable(name="eleve_has_options",
     * joinColumns={
     * @ORM\JoinColumn(name="eleve_ideleve", referencedColumnName="ideleve")
     * },
     * inverseJoinColumns={
     * @ORM\JoinColumn(name="options_idoption", referencedColumnName="idoption")
     * }
     * )
     */
    private $optionsoption;
    /**
     * @var Classe
     *
     * @ORM\ManyToOne(targetEntity="Classe")
     * @ORM\JoinColumns({
     * @ORM\JoinColumn(name="classe_idclasse", referencedColumnName="idclasse")
     * })
     */
    private $classeclasse;
    /**
     * @var Parents
     *
     * @ORM\ManyToOne(targetEntity="Parents")
     * @ORM\JoinColumns({
     * @ORM\JoinColumn(name="parent_idparent", referencedColumnName="idparent")
     * })
     */
    private $parentparent;
    public function __construct()
    {
        $this->optionsoption = new \Doctrine\Common\Collections\ArrayCollection();
    }

    /**
     * Get ideleve
     *
     * @return integer 
     */
    public function getIdeleve()
    {
        return $this->ideleve;
    }
    /**
     * Set nom
     *
     * @param string $nom
     */
    public function setNom($nom)
    {
        $this->nom = $nom;
    }
    /**
     * Get nom
     *
     * @return string 
     */
    public function getNom()
    {
        return $this->nom;
    }
    /**
     * Set prenom
     *
     * @param string $prenom
     */
    public function setPrenom($prenom)
    {
        $this->prenom = $prenom;
    }
    /**
     * Get prenom
     *
     * @return string 
     */
    public function getPrenom()
    {
        return $this->prenom;
    }
    /**
     * Set dateNaissance
     *
     * @param date $dateNaissance
     */
    public function setDateNaissance($dateNaissance)
    {
        $this->dateNaissance = $dateNaissance;
    }
    /**
     * Get dateNaissance
     *
     * @return date 
     */
    public function getDateNaissance()
    {
        return $this->dateNaissance;
    }
    /**
     * Add optionsoption
     *
     * @param LGB\BourseLivresBundle\Entity\Options $optionsoption
     */
    public function addOptions(\LGB\BourseLivresBundle\Entity\Options $optionsoption)
    {
        $this->optionsoption] = $optionsoption;
    }
    /**
     * Get optionsoption
     *
     * @return Doctrine\Common\Collections\Collection 
     */
    public function getOptionsoption()
    {
        return $this->optionsoption;
    }
    /**
     * Set classeclasse
     *
     * @param LGB\BourseLivresBundle\Entity\Classe $classeclasse
     */
    public function setClasseclasse(\LGB\BourseLivresBundle\Entity\Classe $classeclasse)
    {
        $this->classeclasse = $classeclasse;
    }
    /**
     * Get classeclasse
     *
     * @return LGB\BourseLivresBundle\Entity\Classe 
     */
    public function getClasseclasse()
    {
        return $this->classeclasse;
    }
    /**
     * Set parentparent
     *
     * @param LGB\BourseLivresBundle\Entity\Parents $parentparent
     */
    public function setParentparent(\LGB\BourseLivresBundle\Entity\Parents $parentparent)
    {
        $this->parentparent = $parentparent;
    }
    /**
     * Get parentparent
     *
     * @return LGB\BourseLivresBundle\Entity\Parents 
     */
    public function getParentparent()
    {
        return $this->parentparent;
    }
}

Franchement j'ai pas compris depuis 3 jours je me tire les cheveux la dessus merci de votre aide !

Edit : Voici ce que j'ai fais en faisant une requête Symfony

$listeLivres = $this->getDoctrine()->getEntityManager()->createQuery("SELECT livre.codeEan, livre.idlivre FROM LGBBourseLivresBundle:Eleve eleve, LGBBourseLivresBundle:Livre livre, LGBBourseLivresBundle:Classe classe, LGBBourseLivresBundle:ClasseHasOptions classeOpt, LGBBourseLivresBundle:Options options WHERE eleve.classeclasse = classe.idclasse AND eleve.eleve_ideleve = eleve.ideleve AND eleve.options_idoption = options.idoption AND classeOpt.classeIdclasse = eleve.classe_idclasse AND classeOpt.optionsIdoption = eleve.options_idoption AND classeOpt.livreIdlivre = livre.idlivre AND eleve.ideleve = 5 ");
        $test = $listeLivres->getResult();

Seulement comme je ne c'est pas comment appeler certaines colonnes j'ai des erreurs.

[Semantical Error] line 0, col 289 near 'eleve_ideleve': Error: Class LGB\BourseLivresBundle\Entity\Eleve has no field or association named eleve_ideleve

13 réponses


Alex-D
Réponse acceptée

Salut !
Faut écrire ta requête en DQL plutôt... au pire, lis des tutos texte sur Doctrine. Je pense qu'il faut que tu regarde du côté des Repository dans ton cas.

zebulonbof
Réponse acceptée

Je vais remontez le post mais tant pis, ça mettra sur le bon chemin ceux qui passe par ici.

Quand on a des requêtes comme celle ci, on utilise des vues matérialisées(faut pas dormir pendant les cours de bdd !) MySQL dispose de ce système depuis un moment. A ne pas abusé car les vues matérialisées ne prennent pas en compte les index, performance médiocre donc mais un sacrifice à faire pour la maintenabilité du code.

cbtraize
Auteur
Réponse acceptée

C'est ce que j'avais utilisé sur ce projet. Suite au conseil de mon prof. C'était une fonctionnalité que je connaissait pas on l'avais pas vue en cours :)

cbtraize
Auteur

D'accord je vais essayer reste à l'affût de mes réponse merci beaucoup de ta réponse je commençais à désespérer avec symfony ^^

cbtraize
Auteur

Es ce que t’aurais un bon lien ? stp parce que la je vois pas du tout comment faire ! merci

cbtraize
Auteur

Merci je regarde

cbtraize
Auteur

J'ai fais ça :

$qb->select('livre.codeEan, livre.idlivre')
    ->from('LGBBourseLivresBundle:Eleve', 'eleve')
    ->from('LGBBourseLivresBundle:Livre', 'livre')
    ->from('LGBBourseLivresBundle:Classe', 'classe')
    ->from('LGBBourseLivresBundle:ClasseHasOptions', 'classeOpt')
    ->from('LGBBourseLivresBundle:Options', 'options')
    ->where('eleve.classeclasse = classe.idclasse')
    ->andwhere('eleve.eleve_ideleve = eleve.ideleve')
    ->andWhere('eleve.options_idoption = options.idoption')
    ->andWhere('classeOpt.classeIdclasse = eleve.classe_idclasse')
    ->andWhere('classeOpt.optionsIdoption = eleve.options_idoption')
    ->andWhere('classeOpt.livreIdlivre = livre.idlivre')
    ->andWhere('eleve.ideleve = :id')
    ->setParameter('id', $id);
    ->getQuery()
    ->getResult();

;

Mon problème est le même il ne connait pas eleve_ideleve :

[Semantical Error] line 0, col 289 near 'eleve_ideleve': Error: Class LGB\BourseLivresBundle\Entity\Eleve has no field or association named eleve_ideleve

Voici ce que j'ai dans l'entité Eleve :

/**
     * @var Options
     *
     * @ORM\ManyToMany(targetEntity="Options", inversedBy="eleveeleve")
     * @ORM\JoinTable(name="eleve_has_options",
     * joinColumns={
     * @ORM\JoinColumn(name="eleve_ideleve", referencedColumnName="ideleve")
     * },
     * inverseJoinColumns={
     * @ORM\JoinColumn(name="options_idoption", referencedColumnName="idoption")
     * }
     * )
     */
    private $optionsoption;

Si vous pouviez m'aider ça serait vraiment sympas je suis bloquer depuis 5 jours :(

Ta requête me paraît assez énorme... À mon avis t'as pas optimisé tes jointures / Entitées :/

cbtraize
Auteur

j'ai refait ça :

public function GetTest($id)
   {
      $qb = $this->createQueryBuilder('a');
      $qb->select('livre.codeEan, livre.idlivre')
         ->from('LGBBourseLivresBundle:Livre', 'livre')
         ->from('LGBBourseLivresBundle:Classe', 'classe')
         ->from('LGBBourseLivresBundle:ClasseHasOptions', 'classeOpt')
         ->from('LGBBourseLivresBundle:Options', 'options')
         ->join('LGBBourseLivresBundle:Eleve', 'c')
         ->addselect('c')
         ->where('c.classeclasse= classe.idclasse')
         ->andWhere('c.options_idoption = options.idoption')
         ->andWhere('classeOpt.classeIdclasse = c.classe_idclasse')
         ->andWhere('classeOpt.optionsIdoption = c.options_idoption')
         ->andWhere('classeOpt.livreIdlivre = livre.idlivre')
         ->andWhere('c.ideleve = :id')
            ->setParameter('id', $id);
      return $qb->getQuery()
                ->getResult();
   }

J'ai cette erreur :
[Semantical Error] line 0, col 121 near 'c, LGBBourseLivresBundle:Livre': Error: Identification Variable LGBBourseLivresBundle:Eleve used in join path expression but was not defined before.

Quelqu'un pourrait me dire à quoi servent les @JoinColumn ? J'ai fais toute une appli web avec des one to many etc, sans l'utilise... ? Merci d'avance

Quand le nom de tes champs ne sont pas super clairs. Imaginons que tu fasses une relation de BlogComment pour le lier a un BlogPost mais qu'au lieu de lier avec post_id, que ta colonne de liaison c'est quelque chose du genre de postid ou autre. L'ORM ne le reconnaîtra pas automatiquement et il faudra le lui préciser. De même pour le reversed. Doctrine s'attend à link le post_id du comment à un champ id du post. Si ton champ primary s'appelle postid dans ta table post, il va falloir lui préciser de chercher ça et non simplement "id".

Ok Ok, je vois, mais donc tu confirmes bien le fait que l'on peut s'en passer... Merci en tous cas de ta réponse slyvaan !