In a ZF2 - PostgreSQL application, I want to use Doctrine2 native queries to build paginator lists.
So, it works great if any custom Doctrine / Pgsql type is selected. But for one query, I would use data from a custom type.
I have a Doctrine 2 custom type called AlertRecipient
declared in PostgreSQL such as below :
CREATE TYPE alert_recipient AS (
email text,
status int
);
This type is used in some tables. example in a clients
table :
ID (int) | name (varchar) | alerts (alert_recipients[])
1 | John Doe | {"([email protected], 1), ([email protected], 1)"}
2 | Foo Bar | {"([email protected], 1)"}
(alert_recipient[]
extends alert_recipient
to store a list of many alert_recipient
records)
This type is linked to an entity, for hydration :
class AlertRecipient
{
protected $email;
protected $status;
// ... with accessors
}
Doctrine type registration is made on the onBoostrap
event :
// ...
if (!Type::hasType('alert_recipient'))
{
Type::addType('alert_recipient', AlertRecipient::class);
}
$platform->registerDoctrineTypeMapping('alert_recipient', 'alert_recipient');
if (!Type::hasType('alert_recipient[]'))
{
Type::addType('alert_recipient[]', AlertRecipients::class);
}
$platform->registerDoctrineTypeMapping('_alert_recipient', 'alert_recipient[]');
// ...
Custom type doctrine adapter has been written such as the doc http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/cookbook/custom-mapping-types.html
And the query looks like :
$rsm = new ResultSetMappingBuilder($em);
$rsm->addRootEntityFromClassMetadata(Client::class, 'c');
// ... some other data from join entity (e.g)
$query = 'SELECT c.* FROM clients c JOIN ...';
$em->createNativeQuery($query, $rsm);
$results = $query->getResult(NativeQuery::HYDRATE_ARRAY);
Problem is I don't have the same behavior from a find()
Doctrine native method, or from the hydration of my native query result.
Debug in custom type adapter :
public function convertToPHPValue($value, AbstractPlatform $platform)
{
var_dump($value); exit;
// ...
}
Edit
public function convertToPHPValueSQL($sqlExpr, $platform)
{
return 'to_json(' . $sqlExpr . ')';
}
From find()
, result is correctly hydrated used the AlertRecipient
entity : string '[{"email":"[email protected]","status":1}, {"email":"[email protected]","status":1}]'
And from the native query hydration, result['order_emails'] is not hydrated in the AlertRecipient
entity : string '{"([email protected], 1), ([email protected], 1)"}'
Then data are not correctly hydrated ...
Thanks for your ideas
Edit
Declaration of alertRecipient
property in Client
entity :
/* @ORM\Column(type="alert_recipient[]", nullable=true, name="alert_recipients")
* @Gedmo\Versioned
*/
protected $alertRecipients = [];
// ... with accessors