Doctrine2 Multiple Join works with createQuery but not with queryBuilder - php

If I'm using querying without queryBuilder with this dql
$query = $this->_em
->createQuery("SELECT p, g, c
FROM LikeYeah\GoBundle\Entity\Product p
JOIN p.garments g
LEFT JOIN g.colours c
ORDER BY p.id DESC
");
everything is fine, but if I use the (what I belive is the same) query trough query builder like this
$qb->select('p, g, c')
->from('LikeYeah\GoBundle\Entity\Product', 'p')
->join('p.garments', 'g')
->leftJoin('g.colours', 'c')
->orderBy('p.id', 'desc');
I get the following error:
"Semantical Error] line 0, col 66 near '.colours c, LikeYeah\GoBundle\Entity\Product': Error: Identification Variable g used in join path expression but was not defined before."
What am I missing?

Try this: using addSelect after your joins:
$qb->select('p')
->join('p.garments', 'g')
->addSelect('g')
->from('LikeYeah\GoBundle\Entity\Product', 'p')
->join('p.garments', 'g')
->leftJoin('g.colours', 'c')
->addSelect('c')
->orderBy('p.id', 'desc');

You can help from this method
public function findSampleClothingTypeGender($gender) {
$query = $this->getEntityManager()
->createQuery('
SELECT p FROM Acme:Product p
JOIN p.clothing_type ct
WHERE p.gender = :gender'
)->setParameter('gender', $gender);
try {
return $query->getResult();
} catch (\Doctrine\ORM\NoResultException $e) {
return null;
}
}

Try with below one
$qb->select('p','g','c')
->from(array('LikeYeah\GoBundle\Entity\Product','p'))
->join(array('p.garments','g'))
->join(array('g.colours','c'),'LEFT')
->order_by('p.id','DESC');

may be try
$qb->select('p, g, c')
->from('GoBundle:Product', 'p')
->join('p.garments', 'g')
->leftJoin('g.colours', 'c')
->orderBy('p.id', 'desc');
show your $qb init and DQL result

It works for me.
$this->_em->createQueryBuilder()
->select('fu,e,t')
->from('\xxxx\AdminBundle\Entity\FrontUser','fu')
->join('fu.read_essays','e')
->leftJoin('e.tags','t')
->getQuery()->execute();
I think you should create a new QueryBuilder object.
You can use follow code to see Dql of that QueryBuilder
$qb->getDQL();

Related

Doctrine2 - double left join query issue

I am using Symfony v3.4 branch with Doctrine.
I am having trouble translating SQL query to Doctrine ORM query.
I have 3 tables.
Shop
Firm
User
User --> 1:1 --> Firm --> 1:1 --> Shop
(Symfony developer tool bar reports that associations in tables are made correctly).
I want to get Shop data that corresponds to cretain User in one query.
My SQL, that get a result:
SELECT *
FROM mp2_fos_user as u
LEFT JOIN mp2_firm AS f ON u.id = f.firmUserId
LEFT JOIN mp2_shop AS s ON f.id = s.shopFirmId
WHERE u.id = 1
My Doctrine ORM query
$query = $em->createQueryBuilder()
->select('u, f, s')
->from('App:User', 'u')
->leftJoin('u.userFirm WITH u.id = f.firmUserId', 'f')
->leftJoin('f.firmShop WITH f.id = s.shopFirmId', 's')
->where('u.id = :user_id')
->setParameter('user_id', $user_id)
->getQuery();
at the moment running the code results in an error
[Syntax Error] line 0, col 57: Error: Expected end of string, got 'u'
What would be best practice for my issue?
Help would be much appreciated,
Thank you!
UPDATE
tried:
$query = $em->createQueryBuilder()
->select('s.id')
->from('App:User', 'u')
->leftJoin('u.userFirm WITH f.firmUser = u', 'f')
->leftJoin('f.firmShop WITH s.shopFirm = f', 's')
->where('u.id = :user_id')
->setParameter('user_id', $user_id)
->getQuery();
got [Syntax Error] line 0, col 54: Error: Expected end of string, got 'f'
There is no need to use WITH clause if you have defined mapping in your entities, WITH clause is used when you want to join your entities with additional matching criteria
class User
{
/**
* #ORM\YourRelationShipNature(targetEntity="App\Entity\Firm", mappedBy="user")
*/
private $userFirm;
}
class Firm
{
/**
* #ORM\YourRelationShipNature(targetEntity="App\Entity\Shop", mappedBy="firm")
*/
private $firmShop;
}
class Shop
{
//.....
}
And then your could simple use properties to join your entites
$query = $em->createQueryBuilder()
->select('u, f, s')
->from('App:User', 'u')
->leftJoin('u.userFirm', 'f')
->leftJoin('f.firmShop', 's')
->where('u.id = :user_id')
->setParameter('user_id', $user_id)
->getQuery();
I was thinking of something more along the lines of this (assuming the entity names are correct):
$query = $em->createQueryBuilder()
->select('u, f, s')
->from('App:User', 'u')
->leftJoin('App:UserFirm f WITH f.firmUser = u')
->leftJoin('App:FirmShop s WITH s.shopFirm = f')
->where('u.id = :user_id')
->setParameter('user_id', $user_id)
->getQuery();

DQL Subquery Questions

I'm trying to SLECT * FROM a table o where the vendor is what I pass.(this is in the context of a Doctrine Repository). I then want to run a subquery and SELECT * FROM AppBundle:PriceOption where p.offer is o. I'm getting a QueryException when running this code though:
public function getVendorFeaturedDeals(Vendor $vendor){
$purchaseOptions = $this->
getEntityManager()
->createQueryBuilder()
->from('AppBundle:PriceOption', 'p')
->innerJoin('p.offer', 'o')
->getDQL();
$query = $this->createQueryBuilder('o');
return $query
->where('o.vendor = :vendor')
->addSelect(sprintf('(%s)', $purchaseOptions))
->setParameter(':vendor', $vendor)
->getQuery()
->execute();
}
Here's the error : AppBundle\Tests\Service\VendorServiceTest::testGetVendorFeaturedDeals
Doctrine\ORM\Query\QueryException: [Syntax Error] line 0, col 18: Error: Unexpected 'FROM' Caused by Doctrine\ORM\Query\QueryException: SELECT o, (SELECT FROM AppBundle:PriceOption p INNER JOIN p.offer o) FROM AppBundle\Entity\Offer o WHERE o.vendor = :vendor
Any help would be appreciated, thanks!
You should modify your query to:
$purchaseOptions = $this->
getEntityManager()
->createQueryBuilder()
->select(['p', 'o'])
->from('AppBundle:PriceOption', 'p')
->innerJoin('p.offer', 'o')
->getDQL();

How to implement subqueries in Symfony2 with Doctrine?

I need to count the number of items returned in the subquery. If I write the subquery how DQL - all good, but if I try to build a query via QueryBuilder - I get an error.
Subquery DQL:
$qb3 = $this->createQueryBuilder('c')
->select('COUNT(c.id)')
->where('c.id IN (SELECT cl.id FROM Acme\AppBundle\Entity\ClassC cl INNER JOIN Acme\AppBundle\Entity\ClassP p WHERE p.var1 = :var1 AND p.var2 = cl.id GROUP BY cl.id)')
->setParameter('var1', $var);
Subquery via QueryBuilder:
$qb = $this->createQueryBuilder('c');
$qb->select('COUNT(c.id)')
->where(
$qb->expr()->in(
'c.id',
$this->createQueryBuilder('cl')
->select('cl.id')
->innerJoin('Acme\AppBundle\Entity\ClassP', 'p')
->where('p.var1 = :var1')
->setParameter('var1', $var)
->andWhere('p.var2 = cl.id')
->groupBy('cl.id')
->getDQL()
)
);
Both versions return the same DQL.
Error:
screen
Try to move setParameter() to main level of query.
$qb = $this->createQueryBuilder('c');
$qb->select('COUNT(c.id)')
->where(
$qb->expr()->in(
'c.id',
$this->createQueryBuilder('cl')
->select('cl.id')
->innerJoin('Acme\AppBundle\Entity\ClassP', 'p')
->where('p.var1 = :var1')
->andWhere('p.var2 = cl.id')
->groupBy('cl.id')
->getDQL()
)
)
->setParameter('var1', $var);

Extra Where when using Join in Doctrine Query Language

i have the following code in my Entity Repository class:
$qb
->select('d')
->addOrderBy('d.dtrDate', 'DESC')
->where($qb->expr()->isNotNull('d.deletedAt'))
->leftJoin('d.user', 'u')
->where('u.id = :user_id')
->setParameter('user_id', $user->getId());
So basically, I dont want to select an entity where deletedAt property is not null. However it gives me a query like this:
>
SELECT
d0_.id AS id_0,
d0_.dtr_date AS dtr_date_1,
d0_.clock_in AS clock_in_2,
d0_.clock_out AS clock_out_3,
d0_.total_time AS total_time_4,
d0_.memo AS memo_5,
d0_.last_update_IP AS last_update_IP_6,
d0_.created_at AS created_at_7,
d0_.updated_at AS updated_at_8,
d0_.deleted_at AS deleted_at_9,
d0_.user_id AS user_id_10
FROM
daily_time_record d0_
LEFT JOIN user u1_ ON d0_.user_id = u1_.id
WHERE
u1_.id = ?
ORDER BY
d0_.dtr_date DESC
As you can see my first where is not being called. So how can i work on this?
You should read the documents, or read the ORM source to see how things work actually. TO be short, the answer to your question is:
$qb
->select('d')
->leftJoin('d.user', 'u')
->where($qb->expr()->isNotNull('d.deletedAt'))
->andWhere('u.id = :user_id')
->setParameter('user_id', $user->getId())
->orderBy('d.dtrDate', 'DESC');

Doctrine: Convert a createQuery query to createQueryBuilder

This is the current query that I have, and it works fine:
$q = $this->_em->createQuery("SELECT s FROM app\models\Sub s
LEFT JOIN s.case c
WHERE s.type LIKE '%$type'
AND c.id = '$id'");
foreach ($q->getResult() as $row) {
$results[$row->getId()] = $row;
}
I want to convert this to the QueryBuilder API structure, this is what I have so far, but it's not working correctly. (And I need the results as the same format as above).
$q = $this->_em->createQueryBuilder();
$q->add('select', 's')
->add('from', 'app\models\Sub s')
->add('leftJoin', 's.case c')
->add('where', 's.type LIKE :type')
->add('where', 'c.id = :case');
->setParameter('type', "%$type");
->setParameter('case', $id);
And again, this isn't working properly, and I don't know how to get the results in the same format as above. Thanks!
Close, but no cigar. You'll need to learn how to use the Expr classes that comes with Doctrine in order to create the correct WHERE clause.
http://www.doctrine-project.org/docs/orm/2.1/en/reference/query-builder.html#expr-classes
In the example you provided, you are actually aiming for something like this (not tested):
$q->add('select', 's')
->add('from', 'app\model\Sub s')
->add('leftJoin', 's.case c')
->add('where', $q->expr()->andX($q->expr()->like('s.type', ':type'), $q->expr()->eq('case', ':case')))
->setParameter('type', "%$type")
->setParameter('case', $id);
As your WHERE clause gets more complicated, so will the nesting of expressions.

Categories