Open flaushi opened 3 years ago
Running into the same problem in version 2.7.3
Duplicate of https://github.com/doctrine/orm/issues/4415
We've been looking into this with @sir-kain , and it seems that ResultSetMapping::addIndexBy()
does nothing, because it does not know how to map A.title
to an SQL column. This foreach
has nothing to loop on:
https://github.com/doctrine/orm/blob/536b65f02b853cc9c8bfb184d23a4cc4feecf002/lib/Doctrine/ORM/Query/ResultSetMapping.php#L222
Not sure if we should have another lookup map, or if one of those should be modified, here maybe:
I tried and failed to do so by using addFieldResult
, that resulted in an error during hydration later on: https://github.com/doctrine/orm/blob/536b65f02b853cc9c8bfb184d23a4cc4feecf002/lib/Doctrine/ORM/Internal/Hydration/ObjectHydrator.php#L320-L321
$rowData['data']
became not empty and the aliasMap
was missing the required key for the code to continue, which it probably shouldn't.
@sir-kain has written the following test in case anyone wants to continue this:
<?php
declare(strict_types=1);
namespace Doctrine\Tests\ORM\Functional\Ticket;
use Doctrine\ORM\Mapping\Column;
use Doctrine\ORM\Mapping\Entity;
use Doctrine\ORM\Mapping\Id;
use Doctrine\Tests\OrmFunctionalTestCase;
use Exception;
use function var_dump;
/**
* @group GH-9101
*/
class GH9101Test extends OrmFunctionalTestCase
{
protected function setUp(): void
{
parent::setUp();
try {
$this->_schemaTool->createSchema(
[
$this->_em->getClassMetadata(GH9101Author::class),
]
);
// Create author 11/Joe
$author = new GH9101Author();
$author->id = 11;
$author->name = 'Joe';
$author->title = 'Joe';
$this->_em->persist($author);
// Create author 12/Sir
$author1 = new GH9101Author();
$author1->id = 12;
$author1->name = 'Sir';
$author1->title = 'Sir';
$this->_em->persist($author1);
$this->_em->flush();
$this->_em->clear();
} catch (Exception $e) {
}
}
public function testIndexByOk(): void
{
/* $dql = "SELECT 'hello' FROM Doctrine\Tests\ORM\Functional\Ticket\GH9101Author A INDEX BY A.title "; */
$dql2 = "SELECT new Doctrine\Tests\Models\CMS\CmsUserDTO(A.title)
FROM Doctrine\Tests\ORM\Functional\Ticket\GH9101Author A INDEX BY A.title ";
/* $result = $this->_em->createQuery($dql)->getResult(); */
$result2 = $this->_em->createQuery($dql2)->getResult();
/* var_dump($result); */
var_dump($result2);
// $joe = $this->_em->find(GH9101Author::class, 10);
// $alice = $this->_em->find(GH9101Author::class, 11);
// self::assertArrayHasKey('Joe', $result, "INDEX BY A.name should return an index by the name of 'Joe'.");
// self::assertArrayHasKey('Alice', $result, "INDEX BY A.name should return an index by the name of 'Alice'.");
}
}
/**
* @Entity
*/
class GH9101Author
{
/**
* @var int
* @Id
* @Column(type="integer")
*/
public $id;
/**
* @var string
* @Column(type="string")
*/
public $name;
/**
* @var string
* @Column(type="string")
*/
public $title;
public function __construct()
{
}
}
Bump it (version 2.15.3)
Bug Report
Summary
Results from a DTO-query with INDEX BY are not correctly indexed. I am getting standard arrays instead.
Current behavior
if I query
SELECT x.name FROM Entity x INDEX BY x.name
the result is array like['alice' => 'alice', 'bob' => 'bob', ...]
howeverwill return `[0 => Dto('alice'), 1 => DTO('bob'), ...]
Expected behavior
I would expect to get
['alice' =>DTO( 'alice'), 'bob' => DTO('bob'), ...]
In view that partial queries are deprecated and that DTOs should replace them, the index by feature might be important for all developers who used index-by together with partial objects until now and have to migrate. For partial objects, this worked fine.