DDC-1494: Query results are overwritten by previous query. #1874

Closed
opened 2026-01-22 13:29:13 +01:00 by admin · 8 comments
Owner

Originally created by @doctrinebot on GitHub (Nov 15, 2011).

Originally assigned to: @Ocramius on GitHub.

Jira issue originally created by user monk.e.boy:

I am running a query that JOINs three tables, with a simple WHERE:

$q = $em->createQuery("

SELECT cat, n, c
FROM Project*Model*NoticeCategory cat
JOIN cat.notices n
JOIN n.chapters c
WHERE
c.id = :chapter_id

");

When I do this:

  $q->setParameter('chapter_id', 1);
  $a = $q->getResult();

  $q->setParameter('chapter_id', 2);
  $b = $q->getResult();

$b always has the wrong results. Running the following code:

  $q->setParameter('chapter_id', 1);
  $a = $q->getResult();

  $q->setParameter('chapter_id', 2);
  $b = $q->getResult();
  $z = $q->getArrayResult();

BUG Results: $b != $z (getArrayResult IS CORRECT, it refreshes the results) Note: $a==$b (which is wrong)

Explanation:

There is a chapter table, this has a many-to-many join to notices (these are meta info
about the chapter -- a little like tagging a blog post) the notices are grouped into
categories.

Data model:

/****
 * @Entity
 * @Table(name="chapter")
 */
class Project*Model*Chapter
{
    /****
     * @Id @Column(type="integer")
     * @GeneratedValue(strategy="AUTO")
     */
    private $id;

    /*** @Column(type="string") **/
    private $title;

    /****
     * @ManyToMany(targetEntity="Project*Model*Notice", mappedBy="chapters")
     */
    private $notices;

    .... /lots of code snipped/ ....

}


/****
 * @Entity
 * @Table(name="notice")
 */
class Project*Model*Notice
{
    /****
     * @Id @Column(type="integer")
     * @GeneratedValue(strategy="AUTO")
     */
    private $id;

    /*** @Column(type="string") **/
    private $title;

    /****
     * @ManyToMany(targetEntity="Project*Model*Chapter", inversedBy="notices")
     * @JoinTable(name="chapter_notice")
     */
    private $chapters;

    /****
     * @ManyToOne(targetEntity="Project*Model*NoticeCategory", inversedBy="notices")
     */
    private $notice_category;

    .... /lots of code snipped/ ....

}

/****
 * @Entity
 * @Table(name="notice_category")
 */
class Project*Model*NoticeCategory
{
    /****
     * @Id @Column(type="integer")
     * @GeneratedValue(strategy="AUTO")
     */
    private $id;
    /*** @Column(type="string") **/
    private $title;

    /****
     * Bidirectional - One-To-Many (INVERSE SIDE)
     *
     * @OneToMany(targetEntity="Project*Model_Notice", mappedBy="notice*category", cascade={"persist", "remove"})
     */
    private $notices;

    .... /lots of code snipped/ ....

}

Data fixtures:

$tools = new \Project*Model*NoticeCategory;
$tools->setTitle('Tools');

$spanner = new \Project*Model*Notice;
$spanner->setTitle('spanner');
$tools->addNotice($spanner);

$drill = new \Project*Model*Notice;
$drill->setTitle('power drill');
$tools->addNotice($drill);

$this->em->persist($tools);
$this->em->flush();

$tools = new \Project*Model*NoticeCategory;
$tools->setTitle('Safety');

$gloves = new \Project*Model*Notice;
$gloves->setTitle('gloves');
$tools->addNotice($gloves);

$goggles = new \Project*Model*Notice;
$goggles->setTitle('goggles');
$tools->addNotice($goggles);

$this->em->persist($tools);
$this->em->flush();

$chapter1 = new \Project*Model*Chapter;
$chapter1->setTitle('Chapter 1');
$this->em->persist($chapter1);

$chapter2 = new \Project*Model*Chapter;
$chapter2->setTitle('Chapter 2');
$this->em->persist($chapter2);

$chapter1->addNotice($spanner);
$chapter1->addNotice($gloves);

$chapter2->addNotice($spanner);
$chapter2->addNotice($gloves);
$chapter2->addNotice($drill);
$chapter2->addNotice($goggles);

// now persist and flush everything

Initial investigation:

I think it has something to do with HINT_REFRESH ? Stepping through:

ObjectHydrator->_hydrateRow
ObjectHydrator->_getEntity

when it requests the Project_Model_Category from the unit of work, it
seems that the second query is simply grabbing the cached results from
the first results. This MUST be wrong as the second query uses a
different query (the ID changes) and all the results are wrong.

Originally created by @doctrinebot on GitHub (Nov 15, 2011). Originally assigned to: @Ocramius on GitHub. Jira issue originally created by user monk.e.boy: I am running a query that JOINs three tables, with a simple WHERE: ``` $q = $em->createQuery(" SELECT cat, n, c FROM Project*Model*NoticeCategory cat JOIN cat.notices n JOIN n.chapters c WHERE c.id = :chapter_id "); ``` When I do this: ``` $q->setParameter('chapter_id', 1); $a = $q->getResult(); $q->setParameter('chapter_id', 2); $b = $q->getResult(); ``` $b always has the wrong results. Running the following code: ``` $q->setParameter('chapter_id', 1); $a = $q->getResult(); $q->setParameter('chapter_id', 2); $b = $q->getResult(); $z = $q->getArrayResult(); ``` BUG Results: $b != $z (getArrayResult IS CORRECT, it refreshes the results) Note: $a==$b (which is wrong) Explanation: There is a chapter table, this has a many-to-many join to notices (these are meta info about the chapter -- a little like tagging a blog post) the notices are grouped into categories. Data model: ``` /**** * @Entity * @Table(name="chapter") */ class Project*Model*Chapter { /**** * @Id @Column(type="integer") * @GeneratedValue(strategy="AUTO") */ private $id; /*** @Column(type="string") **/ private $title; /**** * @ManyToMany(targetEntity="Project*Model*Notice", mappedBy="chapters") */ private $notices; .... /lots of code snipped/ .... } /**** * @Entity * @Table(name="notice") */ class Project*Model*Notice { /**** * @Id @Column(type="integer") * @GeneratedValue(strategy="AUTO") */ private $id; /*** @Column(type="string") **/ private $title; /**** * @ManyToMany(targetEntity="Project*Model*Chapter", inversedBy="notices") * @JoinTable(name="chapter_notice") */ private $chapters; /**** * @ManyToOne(targetEntity="Project*Model*NoticeCategory", inversedBy="notices") */ private $notice_category; .... /lots of code snipped/ .... } /**** * @Entity * @Table(name="notice_category") */ class Project*Model*NoticeCategory { /**** * @Id @Column(type="integer") * @GeneratedValue(strategy="AUTO") */ private $id; /*** @Column(type="string") **/ private $title; /**** * Bidirectional - One-To-Many (INVERSE SIDE) * * @OneToMany(targetEntity="Project*Model_Notice", mappedBy="notice*category", cascade={"persist", "remove"}) */ private $notices; .... /lots of code snipped/ .... } ``` Data fixtures: ``` $tools = new \Project*Model*NoticeCategory; $tools->setTitle('Tools'); $spanner = new \Project*Model*Notice; $spanner->setTitle('spanner'); $tools->addNotice($spanner); $drill = new \Project*Model*Notice; $drill->setTitle('power drill'); $tools->addNotice($drill); $this->em->persist($tools); $this->em->flush(); $tools = new \Project*Model*NoticeCategory; $tools->setTitle('Safety'); $gloves = new \Project*Model*Notice; $gloves->setTitle('gloves'); $tools->addNotice($gloves); $goggles = new \Project*Model*Notice; $goggles->setTitle('goggles'); $tools->addNotice($goggles); $this->em->persist($tools); $this->em->flush(); $chapter1 = new \Project*Model*Chapter; $chapter1->setTitle('Chapter 1'); $this->em->persist($chapter1); $chapter2 = new \Project*Model*Chapter; $chapter2->setTitle('Chapter 2'); $this->em->persist($chapter2); $chapter1->addNotice($spanner); $chapter1->addNotice($gloves); $chapter2->addNotice($spanner); $chapter2->addNotice($gloves); $chapter2->addNotice($drill); $chapter2->addNotice($goggles); // now persist and flush everything ``` Initial investigation: I think it has something to do with HINT_REFRESH ? Stepping through: ObjectHydrator->_hydrateRow ObjectHydrator->_getEntity when it requests the Project_Model_Category from the unit of work, it seems that the second query is simply grabbing the cached results from the first results. This MUST be wrong as the second query uses a different query (the ID changes) and all the results are wrong.
admin added the BugInvalid labels 2026-01-22 13:29:13 +01:00
admin closed this issue 2026-01-22 13:29:14 +01:00
Author
Owner

@doctrinebot commented on GitHub (Nov 15, 2011):

Comment created by @beberlei:

Fixed formatting

@doctrinebot commented on GitHub (Nov 15, 2011): Comment created by @beberlei: Fixed formatting
Author
Owner

@doctrinebot commented on GitHub (Nov 18, 2011):

Comment created by @beberlei:

are you using result caching?

@doctrinebot commented on GitHub (Nov 18, 2011): Comment created by @beberlei: are you using result caching?
Author
Owner

@doctrinebot commented on GitHub (Nov 21, 2011):

Comment created by monk.e.boy:

This is part of my bootstrap
,
,


$config = new \Doctrine\ORM\Configuration();

$cache = new \Doctrine\Common\Cache\ArrayCache;
$config->setMetadataCacheImpl($cache);
$config->setQueryCacheImpl($cache);

// driver: schema
$driver = $config->newDefaultAnnotationDriver(
    APPLICATION_PATH . '/models'
);
$config->setMetadataDriverImpl($driver);

@doctrinebot commented on GitHub (Nov 21, 2011): Comment created by monk.e.boy: This is part of my bootstrap , , ``` java $config = new \Doctrine\ORM\Configuration(); $cache = new \Doctrine\Common\Cache\ArrayCache; $config->setMetadataCacheImpl($cache); $config->setQueryCacheImpl($cache); // driver: schema $driver = $config->newDefaultAnnotationDriver( APPLICATION_PATH . '/models' ); $config->setMetadataDriverImpl($driver); ```
Author
Owner

@doctrinebot commented on GitHub (Dec 15, 2011):

Comment created by @beberlei:

Cannot reproduce it with the script attached. Can you try to modify this to fail or write your own testcase?

@doctrinebot commented on GitHub (Dec 15, 2011): Comment created by @beberlei: Cannot reproduce it with the script attached. Can you try to modify this to fail or write your own testcase?
Author
Owner

@doctrinebot commented on GitHub (Dec 15, 2011):

Comment created by @beberlei:

Downgraded

@doctrinebot commented on GitHub (Dec 15, 2011): Comment created by @beberlei: Downgraded
Author
Owner

@doctrinebot commented on GitHub (Feb 9, 2013):

Comment created by @asm89:

Please provide extra feedback.

@doctrinebot commented on GitHub (Feb 9, 2013): Comment created by @asm89: Please provide extra feedback.
Author
Owner

@doctrinebot commented on GitHub (Dec 13, 2015):

Imported 1 attachments from Jira into https://gist.github.com/569badd09f4b0e7bbb2c

@doctrinebot commented on GitHub (Dec 13, 2015): Imported 1 attachments from Jira into https://gist.github.com/569badd09f4b0e7bbb2c - [11131_DDC1494Test.php](https://gist.github.com/569badd09f4b0e7bbb2c#file-11131_DDC1494Test-php)
Author
Owner

@malukenho commented on GitHub (Jan 5, 2017):

@Ocramius @lcobucci can't reproduce bug with the provided file. Can be closed as invalid IMO as no feedback was provided since then.

@malukenho commented on GitHub (Jan 5, 2017): @Ocramius @lcobucci can't reproduce bug with the provided file. Can be closed as invalid IMO as no feedback was provided since then.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: doctrine/archived-orm#1874