Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Doctrine 2.1 where foreign key id =?, edit: Fixed in Doctrine 2.2

I've looked at a lot of answers here related to what seems to be a serious lack of functionality in Doctrine 2.1 that may be the result of OOP correctness trumping relational sanity.

I have two tables with a many to one relationship, Articles and Members. A Member can have many published Articles. The annotation on the owning side is

/**
 * @var \Member
 * @ORM\ManyToOne(targetEntity="Member")
 * @ORM\JoinColumns({
 *   @ORM\JoinColumn(name="member_id", referencedColumnName="id")
 * })
 */
 private $member;

I want to get all active articles for member 6, this is a simple query in SQL:

SELECT * FROM mbr_article 
   WHERE active = 1 AND member_id = 6 
   ORDER BY article_id DESC

What I ended up with was

$rep = $this->getDoctrine()->getRepository('SMWMemberBundle:Article');
$q = $rep->createQueryBuilder('a')
     ->leftJoin('a.member','m')    
     ->where('m.id = ?1')
     ->andWhere('a.active = 1')
     ->orderBy('a.id', 'DESC')
     ->setParameter(1, $id)    
     ->getQuery();

which generated

SELECT m0_.id AS id0, m0_.active AS active1, m0_.update_time AS update_time2,
       m0_.content AS content3, m0_.member_id AS member_id4 
   FROM mbr_article m0_ 
   LEFT JOIN mbr_member m1_ ON m0_.member_id = m1_.id 
   WHERE m1_.id = ? AND m0_.active = 1 
   ORDER BY m0_.id DESC

which works and probably isn't much slower, but that JOIN is not needed as I already have the Member object. When I tried it the other way, I got all Articles not just active ones.

I've seen responses such as Can you get a foreign key from an object in Doctine2 without loading that object? that use getEntityIdentifier and mentions improvements coming in the 2.2 where I could say IDENTITY(member).

Is there a reasonable way to do this in Doctrine 2.1? Will the enhancement allow andWhere('IDENTITY(member) = ?') in the query builder?

Edit:

Thanks to @Ocramius, ->where('IDENTITY(a.member) = ?1') does work in Doctrine 2.2

like image 641
Peter Wooster Avatar asked Feb 19 '13 22:02

Peter Wooster


1 Answers

IDENTITY works in WHERE clauses generated by query builder in Doctrine 2.2 eg.

$q = $rep->createQueryBuilder('a')
    ->where('IDENTITY(a.member) = ?1')
    ->andWhere('a.active = 1')
    ->orderBy('a.id', 'DESC')
    ->setParameter(1, $id)    
    ->getQuery();

produces the following SQL:

SELECT m0_.id AS id0, m0_.active AS active1, m0_.update_time AS update_time2, 
       m0_.content AS content3, m0_.member_id AS member_id4 
    FROM mbr_article m0_ 
    WHERE m0_.member_id = ? AND m0_.active = 1 
    ORDER BY m0_.id DESC
like image 92
Peter Wooster Avatar answered Oct 12 '22 09:10

Peter Wooster