1

I'm trying to create and action that returns all Variantset for a given PrivateUser. It's a many-to-many relationship, so there's a connection table in between.

This is the query I'm trying to run

 $variants = $repository->createQuery('SELECT variants 
            FROM AppBundle:PrivUser user 
            JOIN AppBundle:PrivUserVariantset uv
            JOIN AppBundle:Variantset variants 
            WHERE user.iduser=:user_id')
        ->setParameter('user_id', $userid)
        ->getResult();

but it returns:

[Syntax Error] line 0, col 146: Error: Expected =, <, <=, <>, >, >=, !=, got 'variants'

If I try the very same query with a single join, getting for instance the number of Variantsets from the PrivUserVariantset table, it does work. It looks like a syntax error, but I don't manage to find it from the examples I have gathered.

Is this the right way to do this query?

2 Answers 2

1

I think better way to do this would be:

$variantsRepository = $this->getDoctrine()->getRepository('AppBundle:Variantset');
$qb = $variantsRepository->createQueryBuilder('variants'); //'variants' is just alias, it can be whatever you want
$qb->join('variants.privUsers', 'user')
   ->where('user.id = :user_id')->setParameter('user_id', $userid)
   ->getQuery()
   ->getResult();

Edit:

/** @Entity **/
class Variantset
{
    // ...

    /**
     * @ORM\ManyToMany(targetEntity="PrivUser")
     * @ORM\JoinTable(name="Variantset_privUser",
     *      joinColumns={@ORM\JoinColumn(name="iduser", referencedColumnName="id")},
     *      inverseJoinColumns={@ORM\JoinColumn(name="idvariantset", referencedColumnName="id")}
     * )
     **/
    private $privUsers;

    // ...

    public function __construct() {
        $this->privUsers = new \Doctrine\Common\Collections\ArrayCollection();
    }
}
Sign up to request clarification or add additional context in comments.

12 Comments

Could you tell me what variants.privUser is actually referring to? Do I need to have a direct relation between privUser and VariantSet tables? They are connected through PrivUserVariantset, which contains the ManyToOne keys (foreign keys). Sorry if these are stupid questions, it's my first time with Doctrine and I still don't see all the SQL logic behind it.
@MarcSitges It's ok, we all have been there. So in line $qb->join('variants.privUser', 'user') - privUser is the property in your Variantset.php Entity, and yes, the property should have proper relation between Variantset and PrivUser entities, like you said, ManyToMany relation. here is documentation for how setting up relations between entities properly in doctrine. Also I see that you're using AppBundle:PrivUserVariantset in your query and this is neccessary, because you don't need to have that entity.
Also you do have AppBundle/Entity/Variantset.php and AppBundle/Entity/PrivUser.php setted up, right?
Thanks for the answer. Did you mean AppBundle:PrivUserVariantset is unnecessary? It was automatically created by Doctrine when I imported the database schema. I'd prefer not have an ArrayCollection in PrivUser entity containing all its linked Variantsets (like shown in the examples you sent), since the amount of data in the Variantset is huge and this would generate enormous objects. Would be enough defining the relations in the annotation of both PrivUser and Variantset entities?
I can't, haven't got enough reputation yet. I think you can also vote my question to increase mine. Thanks
|
1

Finally I got it to work by changing the columns detailed in the JoinTable annotation: variantid should go on the first joinColumns whereas priv_userid must go on the inverseJoin

Variantset Class:

/**
     * @var ArrayCollection
     *
     * @ORM\ManyToMany(targetEntity="PrivUser")
     * @ORM\JoinTable(name="priv_user_variantset",
     *      joinColumns={@ORM\JoinColumn(name="variantset_varid", referencedColumnName="varid")},
     *      inverseJoinColumns={@ORM\JoinColumn(name="priv_user_priv_userid", referencedColumnName="priv_userid")}
     * )
     **/
    private $privusers;

    // ...

    public function __construct() {
        $this->privUsers = new \Doctrine\Common\Collections\ArrayCollection();
    }

Controller:

$variantsRepository = $this->getDoctrine()->getRepository('AppBundle:Variantset');
        $em = $variantsRepository->createQueryBuilder('variants'); //'variants' is just alias, it can be whatever you want
        $variants = $em->join('variants.privusers', 'user')
           ->where('user.privUserid = :user_id')->setParameter('user_id', $userid)
           ->getQuery()->getResult();

I have only two entities, Varianset and PrivUser, whereas the DB has three tables, one for each entity plus priv_user_variantset, which connects both via ManyToMany relationship.

It works now for the purpose of my API, but if you have any comment, they'll be very welcomed.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.