Select objects with doctrine - symfony

I am looking at three different models/entities. One is called Model:Idea, one is called Model:IdeaDetail and the other is called Model:IdeaDetailValue.
IdeaDetail has a few different columns, including Idea (which is idea_id in the database, but $idea object in my model class) and IdeaDetailValue (idea_detail_value_id in the database, but $ideaDetailValue as an object in the model).
So basically, what I'm trying to do is select out a list of Idea objects by querying IdeaDetail.
$queryBuilder
->select('id.idea')
->from('Model:IdeaDetail', 'id')
->where('IDENTITY(id.ideaDetailValue) IN (:ideaDetailValueIds)')
->setParameter('ideaDetailValueIds', $ideaDetailValueIds)
->getQuery()
->getResult();
This fails though, with this error:
[Semantical Error] line 0, col 10 near 'task FROM Model:IdeaDetail': Error: Invalid PathExpression. Must be a StateFieldPathExpression.
Does anyone know the correct way to do this query?
Thanks

It is wrong to select id.idea (according to the error, in fact, you probably select id.task), and also you cannot use IDENTITY() in this case.
You should join your tables to achieve the desired effect. Something like this should work:
$queryBuilder
->select('idea')
->from('Model:IdeaDetail', 'id')
->leftJoin('Model:IdeaDetailValue', 'idea')
->where('idea.id IN (:ideaDetailValueIds)')
->setParameter('ideaDetailValueIds', $ideaDetailValueIds)
->getQuery()
->getResult();

Related

Doctrine error - expected end of string, got "ORDER"

Using Symfony 4 / Doctrine, I got an error with this query :
$this->createQueryBuilder('s')
->update()
->set('s.dateCreate', ':date_new')
->setParameter('date_new', date('Y-m-d H:i:s'))
->where('s.site = :site')
->setParameter('site', $site)
->orderBy('s.dateCreate', 'DESC')
->setMaxResults(1)
->getQuery()
->execute();
I got this error :
[Syntax Error] line 0, col 81: Error: Expected end of string, got 'ORDER'
If I remove the orderBy, query works but I need to only update last entry. Can't see what is wrong here..
You are make an update statement, where inside it you can't add an order by function in this case.
If you want to order your result you need to make a select instead of an update into another query, you can do both, or you need to make a subselect to update only 1 result for example

Join a subquery with Doctrine DQL

Using Doctrine in Symfony2, I need to recover each items and for each of them, the latest timestamp of their report.
So I would like to execute a query using DQL, which would be like this in SQL:
SELECT * from `item` i
LEFT JOIN `kit` k ON k.`id` = i.`kit_id`
LEFT JOIN
(SELECT e.`item_id`, MAX(e.`dateCreation`)
FROM `entete_rapport` e
GROUP BY e.`item_id`) latest ON latest.`item_id` = i.`id`
I am not able to have the same with DQL. I guess I have to separate the subquery et the main one, with something like this:
$subSelect->select('e AS ItemId, MAX(e.dateCreation) AS latest')
->from('CATUParkBundle:EnteteRapport', 'e')
->groupBy('e.item');
$qb->select('i')
->from('CATUParkBundle:Item', 'i')
->leftJoin('i.kit', 'k')
->leftJoin('CATUParkBundle:EnteteRapport f', sprintf('(%s)', $subSelect->getDQL()), 'latest', 'f.id = latest.ItemId');
I am not able to make this query work, I really need you guys.
Thank you in advance, you're awesome!
Seems like subqueries in joins do not work in dql. (I get error message: [Semantical Error] line 0, col 52 near '(SELECT e': Error: Class '(' is not defined.)
You could run $em->getConnection()->prepare($yourRawSql)->execute()->fetchAll(), but this returns a raw result array (no objects). See raw sql queries on knp-lab
Or do it in dql with HAVING instead of a subquery join:
$qb->select('i', 'i')
->addSelect('MAX(e.dateCreation)', 'date')
->from('CATUParkBundle:Item', 'i')
->leftJoin('i.kit', 'k')
->leftJoin('i.rapportOrWhatEver', 'f')
->groupBy('e.id');

Symfony createQueryBuilder with many to many

In my system candidate and profession has many to many relationship. I need to implement following query in symfony.
SELECT c. *
FROM candidate AS c
LEFT JOIN candidate_profession AS cp ON cp.candidate_id=c.id
WHERE cp.profession_id = 2
So i wrote following code.
$matched = $em->getRepository('AppBundle:Candidate')
->createQueryBuilder('c')
->where('c.professions = :profession')
->setParameter('profession', $job->getProfession())
->getQuery()
->getResult();
$job->getProfession() is return profession object. But it show following error.
[Semantical Error] line 0, col 51 near 'professions =': Error: Invalid PathExpression. StateFieldPathExpression or SingleValuedAssociationField expected.
How i implement that query?
I think your query should look like this:
$em->getRepository('AppBundle:Candidate')
->createQueryBuilder('c')
->leftJoin('c.professions', 'p')
->where('p.id = :profession')
->setParameter('profession', $job->getProfession())
->getQuery()
->getResult();
More about join clauses: http://doctrine-dbal.readthedocs.org/en/latest/reference/query-builder.html#join-clauses
First of all, I don't know where you have placed that snippet of code but I strongly advice you to migrate it into a Repository if you don't have already done (but looking at code I'm not sure you have)
Second, you need to pass an ID as ->getProfession() (as you already noticed) will return the whole object and you don't need it
So your query should be like this
$matched = $em->getRepository('AppBundle:Candidate')
->createQueryBuilder('c')
->where('c.professions = :profession')
->setParameter('profession', $job->getProfession()->getId())
->getQuery()
->getResult();
Please pay attention
You didn't specify the cardinality of relationship between job and profession: if is a something-to-Many you can't simply use ->getId() as returned object is an ArrayCollection, so, in that case, you need to do a loop to extract all id(s) and then use something like "IN" clause

Doctrine Query Builder query some columns in table

I am using Doctrine 2, and I have a request to the database, in the first table(t1) I selected needed columns, and how to select some columns from a table(t2 and t3).
I tried to do so, but I get an error. any idea?
addselect('partial t2.{id, name, description}')
addselect('partial t3.{id, name, description}')
my request
$query = $this->getDoctrine()->getManager()
->getRepository('YourBundle:Entity')
->createQueryBuilder('t1')
->leftJoin('t1.table2', 't2')
->leftJoin('t1.table3', 't3')
->select('partial t1.{id, name, description}')
**->addselect('t2, t3')**
->where('t1.name LIKE :q OR t1.description LIKE :q')
->setParameter('q', $test.'%')
->setMaxResults(16)
->getQuery()
->getArrayResult();
Error with ->addselect('t2, t3'). Do not use a single string. Break up the string into arguments
->addSelect('t2')
->addSelect('t3')
Post any error message you receive.

Filter query using SQL IN statement in doctrine

One branch may have many customers, a customer may be related to many branches. So this is a many to many relation.
Branch:
<many-to-many target-entity="Customer" inversed-by="branches" field="customers"/>
Customer:
<many-to-many field="branches" target-entity="Branch" mapped-by="customers"/>
Now I want to perform following query: Select all customers where customer's branch matches a given branch object.
This is what I tried:
$branch = $em->getRepository('MyBundle:Branch')
->findOneById($bid);
$qb->select(array('c'))
->from('MyBundle:Customer', 'c')
->where($qb->expr()->in('c.branches', $branch))
->andWhere('c.delted = 0')
->getQuery();
So my idea was to use IN statement. But this does not work.
Error:
Fatal error: Object of class DateTime could not be converted to string
..Query\Expr\Func.php on line 48
Any ideas how to do this the right way?
Try add join in your query:
$qb->select(array('c', 'b'))
->from('MyBundle:Customer', 'c')
->join('c.branches', 'b')
->where('b IN (:branch)')
->andWhere('c.deleted = 0')
->setParameter('branch', array($branch))
->getQuery();

Resources