Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Doctrine 2 composite keys and DQL joins

I'm trying to filter out the children where the parent consists of a composite primary key, the parent is called subject and the children is courses:

Subject:

class Subject
{
   /**
     * @var integer
     *
     * @Column(type="integer")
     * @Id
     * @GeneratedValue(strategy="NONE")
     */
    protected $id;

    /**
     * @var integer
     *
     * @Column(type="integer")
     * @Id
     */
    protected $customer_id;

    /**
     * @var ArrayCollection
     *
     * @OneToMany(targetEntity="Course", mappedBy="subject")
     */
    private $courses;

    ...
}

Course:

class Course
{
    ...

    /**
     * @var Subject
     *
     * @ManyToOne(targetEntity="Subject", inversedBy="courses")
     * @JoinColumns({
     *   @JoinColumn(name="subject_id", referencedColumnName="id"),
     *   @JoinColumn(name="subject_customer_id", referencedColumnName="customer_id")
     * })
     */
    private $subject;
}

I have the "subject_id" and "subject_customer_id", my problem is that I can't filter out courses without joining subject, when I write this:

$this->em->createQuery("SELECT c FROM Course c WHERE c.subject = :subject")
    ->setParameters( array('subject' => array( 'subject_id' => $subject_id, 'subject_customer_id' => $subject_customer_id ) ) )
    ->getResult();

I get the following error:

Doctrine\ORM\Query\QueryException [ 0 ]: A single-valued association path expression to an entity with a composite primary key is not supported. Explicitly name the components of the composite primary key in the query.

The only why I can get this working is by inner joining subject, example:

$this->em->createQuery("SELECT c FROM Course c INNER JOIN c.subject s WITH s.id = :subject AND s.customer_id = :customer")
    ->setParameters( array( 'subject' => $subject_id, 'customer' => $customer_id ) )
    ->getResult();

Is there any way to retrieve the courses based on the subject primary keys without joining subject?

like image 832
Dennis Avatar asked Nov 03 '22 03:11

Dennis


1 Answers

As of current date, this logic is not yet supported by DQL (see also https://github.com/doctrine/doctrine2/blob/2.3.2/lib/Doctrine/ORM/Persisters/BasicEntityPersister.php#L1641-L1643 ).

You will have to join with something like:

SELECT
    c
FROM
    Course c
INNER JOIN 
    c.subject s 
WHERE 
    s.id = :subject 
    AND 
    s.customer_id = :customer

Consider contributing to the project by adding such logic eventually: it may be merged into the new 2.4 series.

like image 108
Ocramius Avatar answered Nov 18 '22 11:11

Ocramius