'Doctrine 3 native query
I'm trying to make a native query with Doctrine 3 (in a Symfony 6 context). My problem took place when I switched from MySQL to PostgreSQL. My code work with MySQL and the native query itself is right.
This query is a bit complex in sense that I'm using Union, non-mapped/entity based result and also a concat on embedded entity fields (even if this shouldnt be a problem in a native query)
I've got a bunch of entity joined:
Customer -> CustomerSite -> CustomerSiteContact
Prospect -> ProspectSite -> ProspectSiteContact
Supplier -> SupplierContact
I'll only show you how is my Customer and its joined entity because the logic is the same for the other entity.
My model
#[ORM\Entity]
class Customer extends Aggregate
{
use TimeStampableTrait;
use SoftDeletableTrait;
#[ORM\Id, ORM\Column(type: 'integer', options: ['unsigned' => true]), ORM\GeneratedValue(strategy: 'IDENTITY')]
protected int $id;
#[ORM\Column(type: 'string', length: 50)]
protected string $customerCode;
#[ORM\ManyToOne(targetEntity: Agency::class, inversedBy: 'customers')]
protected Agency $agency;
#[ORM\Column(type: 'string', length: 255)]
protected string $name;
#[ORM\Embedded(class: EmbeddableAddress::class, columnPrefix: false)]
protected EmbeddableAddress $address;
#[ORM\OneToMany(mappedBy: 'customer', targetEntity: CustomerSite::class, cascade: ['persist'])]
protected Collection $sites;
//...
}
#[ORM\Entity]
class CustomerSite extends Aggregate
{
#[ORM\Id, ORM\Column(type: 'integer', options: ['unsigned' => true]), ORM\GeneratedValue(strategy: 'IDENTITY')]
protected int $id;
#[ORM\Column(type: 'uuid', unique: true)]
protected UuidInterface $uuid;
#[ORM\Column(type: 'string', length: 255)]
protected string $name;
#[
ORM\ManyToOne(targetEntity: Customer::class, inversedBy:'sites'),
ORM\JoinColumn(nullable: false)
]
protected Customer $customer;
#[ORM\Column(type: 'string', length: 50)]
protected string $phone;
#[ORM\Column(type: 'string', length: 180)]
protected string $email;
#[ORM\Embedded(class: EmbeddableAddress::class, columnPrefix: false)]
protected EmbeddableAddress $address;
#[ORM\OneToMany(mappedBy: 'site', targetEntity: CustomerSiteContact::class, cascade: ['persist', 'remove'])]
protected Collection $contacts;
//...
}
#[ORM\Entity]
class CustomerSiteContact extends Aggregate
{
use TimeStampableTrait;
use SoftDeletableTrait;
#[ORM\Id, ORM\Column(type: 'integer', options: ['unsigned' => true]), ORM\GeneratedValue(strategy: 'IDENTITY')]
protected int $id;
#[ORM\Column(type: 'uuid', unique: true)]
protected UuidInterface $uuid;
#[ORM\ManyToOne(targetEntity: CustomerSite::class, inversedBy: 'contacts')]
#[ORM\JoinColumn(nullable: false)]
protected CustomerSite $site;
#[ORM\Embedded(class: EmbeddablePersonInformation::class, columnPrefix: false)]
protected EmbeddablePersonInformation $contactInformation;
#[ORM\Column(type: 'string', length: 50)]
protected string $functionInCompany;
//...
}
And the embeddable address
#[ORM\Embeddable]
class EmbeddableAddress
{
#[ORM\Column(type: 'string', length: 200, nullable: true)]
protected ?string $street;
#[ORM\Column(type: 'string', length: 10, nullable: true)]
protected ?string $zipcode;
#[ORM\Column(type: 'string', length: 50, nullable: true)]
protected ?string $city;
#[ORM\Column(type: 'string', length: 56, nullable: true)]
protected ?string $country;
//...
}
And finally the embeddable Address
#[ORM\Embeddable]
class EmbeddablePersonInformation
{
#[ORM\Column(type: 'string', length: 50)]
protected string $firstname;
#[ORM\Column(type: 'string', length: 50)]
protected string $lastname;
#[ORM\Column(type: 'string', length: 101)]
protected string $displayName;
#[ORM\Column(type: 'string', length: 50)]
protected string $phone1;
#[ORM\Column(type: 'string', length: 50, nullable: true)]
protected ?string $phone2;
#[ORM\Column(type: 'string', length: 180)]
protected string $email;
//...
}
Here is what I'm trying
public function findRequestersByAgencies(Collection $agencies, Client $client): array
{
$rsm = new ResultSetMapping();
$rsm
->addScalarResult(columnName: 'contactName', alias: 'contactName')
->addScalarResult(columnName: 'contactUuid', alias: 'contactUuid')
->addScalarResult(columnName: 'contactPhone', alias: 'contactPhone')
->addScalarResult(columnName: 'contactEmail', alias: 'contactEmail')
->addScalarResult(columnName: 'contactJobTitle', alias: 'contactJobTitle')
->addScalarResult(columnName: 'requesterDenomination', alias: 'requesterDenomination')
->addScalarResult(columnName: 'requesterCode', alias: 'requesterCode')
->addScalarResult(columnName: 'siteName', alias: 'siteName')
->addScalarResult(columnName: 'siteUuid', alias: 'siteUuid');
return $this->em->createNativeQuery(
<<<SQL
SELECT csc.display_name as contactName, csc.uuid as contactUuid, csc.phone1 as contactPhone, csc.email as contactEmail, csc.function_in_company as contactJobTitle,
c.name as requesterDenomination, c.customer_code as requesterCode, 'customer' as requesterType,
cs.name as siteName, cs.uuid as siteUuid, CONCAT(cs.street, ' - ', cs.zipcode, ' ', cs.city) as siteAddress
FROM customer c
LEFT JOIN customer_site cs ON c.id = cs.customer_id
LEFT JOIN customer_site_contact csc ON cs.customer_id = c.id
WHERE c.agency_id IN (:customer_agencies_uuid)
UNION ALL
SELECT sc.display_name as contactName, sc.uuid as contactUuid, sc.phone1 as contactPhone, sc.email as contactEmail, sc.function_in_company as contactJobTitle,
s.name as requesterDenomination, s.supplier_code as requesterCode, 'supplier' as requesterType,
null as siteName, null as siteUuid, null as siteAddress
FROM supplier s
LEFT JOIN supplier_contact sc ON sc.supplier_id = s.id
WHERE s.client_id = :client
UNION ALL
SELECT psc.display_name as contactName, psc.uuid as contactUuid, psc.phone1 as contactPhone, psc.email as contactEmail, psc.function_in_company as contactJobTitle,
p.name as requesterDenomination, p.prospect_code as requesterCode, 'prospect' as requesterType,
ps.name as siteName, ps.uuid as siteUuid, CONCAT(ps.street, ' - ', ps.zipcode, ' ', ps.city) as siteAddress
FROM prospect p
LEFT JOIN prospect_site ps on p.id = ps.prospect_id
LEFT JOIN prospect_site_contact psc on ps.prospect_id = p.id
WHERE p.agency_id IN (:prospect_agencies_uuid)
SQL,
$rsm
)->setParameter('customer_agencies_uuid', $agencies)
->setParameter('prospect_agencies_uuid', $agencies)
->setParameter('client', $client)
->getArrayResult();
}
I dont get any error, just an empty array as result. The request is fine as i can use it with
php bin/console doctrine:query:sql "the query..."
If anyone could help me, it would be awesome !
Thanks by advance
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|
