- Ymox,
Bonjour !
Aujourd’hui, j’ai un petit truc particulier dans un projet qui utilise Doctrine hors Symfony — dans le CMS Concrete5.
Mes entités sont dans un package Concrete5, ce qui fait que quand je l’installe, les tables correspondantes sont automatiquement créés. Mais cela ne valide apparemment pas totalement les classes. Et comme les mappings sont apparemment acceptés que par annotations et que je n’en ai pas trop l’habitude, j’ai peut-être loupé un truc.
Le souci survient quand je tente de récupérer une entité en utilisant un QueryBuilder personnalisé, avec toute une série de jointures — je récupère l’objet principal, des objets liés par une "OneToManyToOne", et des objets enfants de l’objet principal, avec les mêmes types d’objets liés. Là où je ne comprends pas, c’est que l’erreur qui m’est retournée est au niveau de la syntaxe de la requête SQL résultante : les jointures sur une des tables se présentent sous la forme … LEFT JOIN ON LEFT JOIN …
, donc aucune table de spécifiée, ni aucune clause de liaison. Doctrine ne râle pas parce que la relation n’existe pas, donc ça semble être bon, mais…
J’ai tenté de supprimer tous les caches que j’avais sous le pointeur (ce qui m’a permis de régler déjà des trucs liés au pseudo-PSR-4 de Concrete5), j’ai activé un mode qui fait que Doctrine me re-génère les proxies à la volée, mais apparemment sans grande chance.
Est-ce que ça a déjà fait le coup à quelqu’un ?
Je fournis mon code, à tout hasard — les trois entités concernées et le repository où se trouve le QueryBuilder qui me serait nécessaire.
Merci d’avance
<?php
namespace Concrete\Package\EShop\Src\Entity;
/**
* @Entity(repositoryClass="\Concrete\Package\EShop\Src\Repository\ProductRepository")
* @Table(name="eshop_product")
*/
class Product
{
/**
* @Id
* @Column(type="integer")
* @GeneratedValue
*/
private $id;
/**
* @Column(type="string")
* @var string
*/
private $name;
/**
* @Column(type="string")
* @var string
*/
private $slug;
/**
* @Column(type="integer")
* @var integer
*/
private $quantity;
/**
* @Column(type="decimal", precision=6, scale=2)
* @var string
*/
private $price;
/**
* @Column(type="text", nullable=true)
* @var text
*/
private $description;
/**
* @ManyToOne(targetEntity="Product", inversedBy="articles")
* @JoinColumn(name="product_id", referencedColumnName="id", nullable=true)
* @var Product
*/
private $product;
/**
* @OneToMany(targetEntity="Product", mappedBy="product")
* @var \Doctrine\Common\Collections\ArrayCollection
*/
private $articles;
/**
* @ManyToMany(targetEntity="\Concrete\Package\EShop\Src\Entity\Feature", mappedBy="product")
* @JoinTable(name="article_feature")
* @var \Doctrine\Common\Collections\ArrayCollection
*/
private $features;
public function __construct()
{
$this->articles = new \Doctrine\Common\Collections\ArrayCollection();
$this->features = new \Doctrine\Common\Collections\ArrayCollection();
}
// …
}
<?php
namespace Concrete\Package\EShop\Src\Entity;
/**
* @Entity
* @Table(name="eshop_feature")
*/
class Feature
{
/**
* @Id
* @Column(type="bigint")
* @GeneratedValue
* @var bigint
*/
private $id;
/**
* @Column(type="text", name="`value`")
* @var string
*/
private $value;
/**
* @ManyToMany(targetEntity="\Concrete\Package\EShop\Src\Entity\Product", inversedBy="features")
* @var \Doctrine\Common\Collections\ArrayCollection
*/
private $products;
/**
* @ManyToOne(targetEntity="\Concrete\Package\EShop\Src\Entity\Property", inversedBy="values")
* @JoinColumn(nullable=false)
* @var \Concrete\Package\EShop\Src\Entity\Property
*/
private $property;
public function __construct()
{
$this->products = new \Doctrine\Common\Collections\ArrayCollection();
}
// …
}
<?php
namespace Concrete\Package\EShop\Src\Entity;
/**
* @Entity
* @Table(name="eshop_property")
*/
class Property
{
/**
* @Id
* @Column(type="integer")
* @GeneratedValue
* @var integer
*/
private $id;
/**
* @Column(type="string")
* @var string
*/
private $name;
/**
* @OneToMany(targetEntity="Feature", mappedBy="property")
* @var \Doctrine\Common\Collections\ArrayCollection
*/
private $values;
public function __construct()
{
$this->values = new \Doctrine\Common\Collections\ArrayCollection();
}
// …
}
<?php
namespace Concrete\Package\EShop\Src\Repository;
class ProductRepository extends \Doctrine\ORM\EntityRepository
{
public function findAll()
{
$qb = $this->getQueryBuilderFindAll();
return $qb->getQuery()->getResult();
}
public function getQueryBuilderFindAll()
{
$qb = $this->createQueryBuilder('p');
$qb ->leftJoin('p.features', 'f')->addSelect('f')
->leftJoin('f.property', 'pr')->addSelect('pr')
->leftJoin('p.articles', 'a')->addSelect('a')
->leftJoin('a.features', 'f2')->addSelect('f2')
->leftJoin('f2.property', 'pr2')->addSelect('pr2');
return $qb;
}
}