Reputation: 8520
I would like to create a Doctrine Native Query, which creates a list of properly hydrated Entity objects. These should be "known" to the entity manager. There is one field in the Entity, which should not be managed by the ORM. It should not be part of any query etc. Therefore it has no ORM specific metadata attached to it. In the example below, this field is called "version". It should be populated by the native query result.
Is there a way this can be achieved with native queries?
When I try to use addFieldResult
$rsm = new ResultSetMapping();
$rsm->addEntityResult(Foo::class, 'f');
$rsm->addFieldResult('f', 'id', 'id');
$rsm->addFieldResult('f', 'name', 'name');
$rsm->addFieldResult('f', 'version', 'version');
$query = $this->entityManager->createNativeQuery("SELECT id, name, '1.0.1' as version FROM foo", $rsm);
$foos = $query->getResult();
I get
In AbstractHydrator.php line 422:
Warning: Undefined array key "version"
Which makes sense, since the "version" has no metadata.
When I treat the Entity object as an DTO:
$rsm->addScalarResult('id', 'id', 'integer');
$rsm->addScalarResult('name', 'name', 'string');
$rsm->addScalarResult('version', 'version', 'string');
$rsm->newObjectMappings['id'] = [
'className' => Foo::class,
'objIndex' => 0,
'argIndex' => 0,
];
$rsm->newObjectMappings['name'] = [
'className' => Foo::class,
'objIndex' => 0,
'argIndex' => 1,
];
$rsm->newObjectMappings['version'] = [
'className' => Foo::class,
'objIndex' => 0,
'argIndex' => 2,
];
This creates "objects" of the Entity - but these are then "unknown" to the entity manager and we get errors like Detached entity App\Entity\Foo@388 cannot be removed
when trying to remove any of the results objects.
This is the Entity class:
<?php
namespace App\Entity;
use App\Repository\FooRepository;
use Doctrine\ORM\Mapping as ORM;
#[ORM\Entity(repositoryClass: FooRepository::class)]
class Foo
{
#[ORM\Id]
#[ORM\GeneratedValue]
#[ORM\Column]
private ?int $id = null;
#[ORM\Column(length: 255)]
private ?string $name = null;
private ?string $version = null;
// this is needed by the scalar results mapping.
// public function __construct(?int $id, ?string $name, ?string $version)
// {
// $this->id = $id;
// $this->name = $name;
// $this->version = $version;
// }
public function getId(): ?int
{
return $this->id;
}
public function getName(): ?string
{
return $this->name;
}
public function setName(string $name): static
{
$this->name = $name;
return $this;
}
public function getVersion(): ?string
{
return $this->version;
}
public function setVersion(string $version): static
{
$this->version = $version;
return $this;
}
}
Upvotes: 0
Views: 14