I use the query builder of Symfony and I have this query:
->select('partial detail.{id}')
->from('Shopware\Models\Article\Detail', 'detail')
->innerJoin('detail.attribute', 'attr')
->leftJoin('detail.article', 'article')
Now I have a custom model outside of this scope with the following relation:
class Supplier {
/**
* #var \Shopware\Models\Article\Supplier
* #ORM\ManyToMany(targetEntity="\Shopware\Models\Article\Supplier")
* #ORM\JoinTable(name="fp_demand_planning_supplier_manufacturers", joinColumns={#ORM\JoinColumn(name="supplier_id", referencedColumnName="id")}, inverseJoinColumns={#ORM\JoinColumn(name="manufacturer_id", referencedColumnName="id", unique=true)})
*/
private $manufacturers;
On the article side the model \Shopware\Models\Article\Supplier is stored in article.supplier.
So now I want to join my custom model with the query above as follows:
->select('partial detail.{id}')
->from('Shopware\Models\Article\Detail', 'detail')
->innerJoin('detail.attribute', 'attr')
->leftJoin('detail.article', 'article')
->innerJoin('FpDemandPlanning\Models\Supplier', 'fps', 'WITH', 'article.supplier = fps.manufacturers');
Here I get this error:
206 near 'manufacturers': Error: Invalid PathExpression. StateFieldPathExpression or SingleValuedAssociationField expected.
I also tried it this way:
->innerJoin('FpDemandPlanning\Models\Supplier', 'fps', 'WITH', 'article.supplier IN (fps.manufacturers)');
But then I get this error:
[Syntax Error] line 0, col 216: Error: Expected Literal, got 'fpSupplier' in
Does anybody know how I can join a custom model that has a many to many relation here?
Thanks!
Related
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
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');
Goal: Ordering my entities on how ofter they are used on associated relations (oneToMany)
The problem: DQL, it somehow handles the FROM keyword is an entity or class.
The Exception thrown: QueryException: [Semantical Error] line 0 col 103 near 'FROM MyBundle:Entity Error: Class 'FROM' is not defined.
Here is a SQL query I wrote to test how to get the data. It works perfectly
SELECT en.id, (COUNT(DISTINCT ag.artist_id) + COUNT(DISTINCT rg.release_id) + COUNT(DISTINCT tg.track_id)) AS total
FROM myapp.entity AS en
LEFT JOIN myapp.other_one AS o1 ON o1.entity_id = en.id
LEFT JOIN myapp.other_two AS o2 ON o2.entity_id = en.id
GROUP BY en.id
ORDER BY total DESC ;
To get the data in symfony to hydrate to objects I try to use Doctrine Query Language in the EntityRepository like this:
/**
* Find Most Common Entities
*
* #return array
*/
public function findMostCommon()
{
$em = $this->getEntityManager();
$qb = $em->createQueryBuilder();
$qb
->select('en, (COUNT(DISTINCT en.other1) + COUNT(DISTINCT en.other2)) AS count')
->from('MarulaBundle:Entity', 'en')
->leftJoin('MyBundle:Other1', 'o1', 'WITH', 'o1.entity = en.id')
->leftJoin('MyBundle:Other2', 'o2', 'WITH', 'o2.entity = en.id')
->groupBy('en')
->orderBy('count', 'DESC')
;
return $qb->getQuery()->getResult();
}
Since it is possible in a SQL query. I was hoping it would work just as fine with DQL.
Has anyone experienced this error before? Is it even possible to achieve this with Doctrine, or is doctrine limited relating this issue?
OOPS: I should not use the keyword "count"
Solution:
->select('en, (COUNT(DISTINCT en.other1) + COUNT(DISTINCT en.other2)) AS HIDDEN orderCount')
note: adding the HIDDEN keyword helps to get only the entities back, which makes the hydration fit right in
I got an error [Syntax Error] line 0, col 81: Error: Expected Literal, got 'NULL' when I try to execute query via query builder
$qb = $this->createQueryBuilder('r')
->select('r')
->where('r.query = :query')
->setParameter('query', $query)
->andWhere('r.lang = NULL')
;
return $qb->getQuery()->getOneOrNullResult();
r.lang field is defined as:
/**
* #var integer
*
* #ORM\ManyToOne(targetEntity="\BW\LocalizationBundle\Entity\Lang")
* #ORM\JoinColumn(name="lang_id", referencedColumnName="id")
*/
private $lang;
Help to solve error, please
When you check for NULL value the expression should be
->andWhere('r.lang IS NULL')
I am using doctrine2 with symfony2 and I am trying to perform a simple select query:
I want to run:
SELECT * FROM table WHERE status in (1, -1)
This PHP code:
$queryBuilder = $this->_em->createQueryBuilder();
$queryBuilder
->select('n')
->from('MyBundle:Table', 'n')
->where('n.status IN (1, -1)');
return $queryBuilder->getQuery()->getResult();
Gives the following exception:
[Syntax Error] line 0, col 96: Error: Expected Literal, got '-'
This is the attribute definition within the entity:
/**
* #var integer
*
* #ORM\Column(name="status", type="integer", nullable=true)
*/
private $status;
If I use only positive numbers within the in argument, it will work. The exception only happens with negative numbers.
What causes this exception?
Should do the trick :
$queryBuilder = $this->_em->createQueryBuilder();
$queryBuilder
->select('n')
->from('MyBundle:Table', 'n')
->where('n.status IN (:status)')
->setParameter('status', array(1, -1));
I have query with two MtM relations:
$em = $this->getEntityManager();
$qb = $em->createQueryBuilder();
$qb
->select('o')
->from('UserBundle:User', 'o')
;
$qb->join('o.organisations', 'org')
->where('org.id = :organisation')
->setParameter('organisation', $filterData['organisation'])
;
$qb
->join('o.scientificDirections', 'd')
->where('d.id IN (:directionIds)')
->setParameter('directionIds', $directionIds)
->orderBy('o.surname')
;
return $qb->getQuery();
But it gives me error: Invalid parameter number: number of bound variables does not match number of tokens.
Can anybody explain me what is wrong?
Relation in User model:
/**
* #ORM\ManyToMany(targetEntity="\StrangeBundle\Entity\ScientificDirection")
*
*/
protected $scientificDirections;
/**
* #ORM\ManyToMany(targetEntity="\StrangeBundle\Entity\Organisation", mappedBy="workers")
*/
protected $organisations;
I think the reason is because you used where twice. That overwrites the first where, which is why it is giving you the parameters number error.
Use andWhere