DQL - leftJoin() error: Expected Literal, got 'JOIN'
Asked Answered
C

1

5

This code:

$builder->select('p')
    ->from('ProProposalBundle:Proposal', 'p')
    ->leftJoin('ProProposalBundle:Proposal:Vote', 'v')
    ->leftJoin('ProUserBundle:User', 'u')
    ->andWhere('v.proposal = p')
    ->andWhere('v.user = u')
    ->andWhere('v.decision = "in_favor" OR v.decision = "against"')
    ->andWhere('u = :user')
    ->setParameter('user', $options['user'])
    ->andWhere('p.community = :community')
    ->setParameter('community', $community)
    ->andWhere('p.archived = :archived')
    ->setParameter('archived', $options['archived'])
    ->leftJoin('p.convocation', 'c')
    ->andWhere("p.convocation IS NULL OR c.status = '" . Convocation::STATUS_PENDING . "'");

    return $builder->getQuery()->execute();

is returning an error:

[Syntax Error] line 0, col 106: Error: Expected Literal, got 'JOIN'

This is the formed query:

SELECT p FROM ProProposalBundle:Proposal p LEFT JOIN ProProposalBundle:Proposal:Vote v LEFT JOIN ProUserBundle:User u LEFT JOIN p.convocation c WHERE v.proposal = p AND v.user = u AND (v.decision = "in_favor" OR v.decision = "against") AND u = :user AND p.community = :community AND (p.convocation IS NULL OR c.status = 'pending') ORDER BY p.created desc

LEFT JOIN is missing the ON or WITH condition. The question is: what am I doing wrong with DQL query? Am I wrong with leftJoin() method?

Consent answered 26/3, 2014 at 10:32 Comment(0)
C
14

Doctrine ORM needs you to tell which relation is joined, not the entity itself (you did it well with p.convocation) :

$builder->select('p')
    ->from('ProProposalBundle:Proposal', 'p')
    ->leftJoin('ProProposalBundle:Proposal\Vote', 'v', 'WITH', 'v.proposal = p AND v.user = :user AND (v.decision = :in_favor OR v.decision = :against)')
    ->setParameter('user', $options['user'])
    ->setParameter('in_favor', 'in_favor')
    ->setParameter('against', 'against')
    ->andWhere('p.community = :community')
    ->setParameter('community', $community)
    ->andWhere('p.archived = :archived')
    ->setParameter('archived', $options['archived'])
    ->leftJoin('p.convocation', 'c')
    ->andWhere("p.convocation IS NULL OR c.status = :pending")
    ->setParameter('pending', Convocation::STATUS_PENDING);

return $builder->getQuery()->execute();

edit: I inversed Vote relation as you commented and removed useless WHERE clauses (Doctrine automatically resolves JOIN ON clause. I also transferred some WHERE clauses about joins in the optional params (WITH in DQL).

edit2: Without relation between Proposal and Vote, not sure it works.

edit3: Best practice is to use setParameter for all values in WHERE clauses.

Cordova answered 26/3, 2014 at 11:3 Comment(8)
Oh! Well. The thing is that p.vote does not exist (only v.proposal). and neither p.user (only v.user).Consent
You should have inversed relations like p.votes and you can use v.user (I edited my answer)Cordova
Any way to achieve it without adding relation like p.votes? It must be possible.Consent
Try my second edit, not sure it works like that but this link makes me confident : #11116928Cordova
Now I'm getting this error: [Syntax Error] line 0, col 158: Error: Expected Literal, got '"' . New query is SELECT p FROM ProProposalBundle:Proposal p LEFT JOIN ProProposalBundle:Proposal:Vote v WITH v.proposal = p AND v.user = :user AND (v.decision = "in_favor" OR v.decision = "against") LEFT JOIN p.convocation c WHERE p.community = :community AND (p.convocation IS NULL OR c.status = 'pending')Consent
It was due to the double quotes. Now, I'm getting this error: [Semantical Error] line 0, col 108 near 'proposal = p': Error: Class Pro\ProposalBundle\Entity\Proposal has no field or association named proposal. But v.proposal exists in ProProposalBundle:Proposal:Vote, not in ProProposalBundle:Proposal. Any idea?Consent
Solved! It was the Vote class definition. Solved replacing ProProposalBundle:Proposal:Vote with ProProposalBundle:Proposal\Vote.Consent
Thank you! I think you are missing : before against (line 3)Consent

© 2022 - 2024 — McMap. All rights reserved.