orm: Identity map error when running SELECT on the same table alias more than once

BC Break Report

Q A
BC Break yes
Version 2.16.0

Summary

Upon upgrading to 2.16, the fetch queries for the entity “Foo” started throwing the following:

(Bar@13041) has no identity/no id values set. It cannot be added to the identity map. 

I went absolutely crazy searching for the issue. Note, Bar is a 3rd degree association to Foo-there are 2 entities between Foo and Bar!

After much digging, I found that the problem comes from the many joins we have on Foo and its associated entities. There are many joins on Foo and when all of the aliases were first written, one of the aliases was entered twice when passed into the array for select. Removing this duplicate join-table alias from the array passed into select resolved the issue.

I’m not 100% certain that the new behavior is a “bug” per-se, but it seems like it breaking change that should be noted.

Previous behavior

Querying the DB with multiple of the same table alias selected would return results without error.

Current behavior

Querying the DB returns with multiple of the same selected table alias causes an identity mapping error.

How to reproduce

Add joins to an entity, call a select statement with an argument of an array that includes the same join alias twice, e.g.

$qb->leftJoin("{$a}.foo", "joinFoo")
      ->leftJoin("{$a}.bar", 'joinBar');
$qb->select([
            self::TABLE_ALIAS,
            'joinFoo',
            'joinBar',
            'joinFoo'
]);

About this issue

  • Original URL
  • State: open
  • Created a year ago
  • Reactions: 2
  • Comments: 16 (8 by maintainers)

Commits related to this issue

Most upvoted comments

I managed to replicate the problem with a minimum of code with doctrine/orm 2.16.1

Create this entities

use Doctrine\ORM\Mapping as ORM;

#[ORM\Entity, ORM\Table(name: 'user')]
class User
{
    #[ORM\Id, ORM\Column]
    private int $id;
}

#[ORM\Entity, ORM\Table(name: 'finger')]
class Finger
{
    #[ORM\Id, ORM\Column]
    private int $id;
}

#[ORM\Entity, ORM\Table(name: 'hand')]
class Hand
{
    #[ORM\OneToOne, ORM\Id]
    private User $user;

    #[ORM\ManyToOne]
    private ?Finger $thumb;
}

Create the MySQL database

create table finger
(
    id int not null primary key
);

create table user
(
    id int not null primary key
);

create table hand
(
    userId  int not null primary key,
    thumbId int null
);

INSERT INTO user (id) VALUES (1);
INSERT INTO hand (userId, thumbId) VALUES (1, null);

And then execute this query

        $entityManager
            ->getRepository(Hand::class)
            ->createQueryBuilder('hand')
            ->leftJoin('hand.thumb', 'thumb')->addSelect('thumb')
            ->getQuery()
            ->getResult();

It should produce this error

The given entity of type ‘Finger’ (Finger@471) has no identity/no id values set. It cannot be added to the identity map.

If you create a finger and set a finger NOT NULL in the hand, no error If you join but not addSelect in the query, no error If the Hand use a simple int as ID instead of a relation, no error If you rollback doctrine/orm to v2.15, no error

I hope it will help you identify the issue

Here https://github.com/doctrine/orm/pull/11194 is my PR which seems to fix the issue, at least for my case