Doctrine Object Mapping Type

Doctrine has support for the Serialize LOB pattern. There are plenty of predefined mapping types you can use in order to match Entity attributes with database columns or even tables. One of those mappings is the object type, which maps an SQL CLOB to a PHP object using serialize() and unserialize().

According to the Doctrine DBAL 2 Documentation, object type:

Maps and converts object data based on PHP serialization. If you need to store an exact representation of your object data, you should consider using this type as it uses serialization to represent an exact copy of your object as string in the database. Values retrieved from the database are always converted to PHP's object type using unserialization or null if no data is present.

This type will always be mapped to the database vendor's text type internally as there is no way of storing a PHP object representation natively in the database. Furthermore this type requires a SQL column comment hint so that it can be reverse engineered from the database. Doctrine cannot correctly map back this type correctly using vendors that do not support column comments, and will instead fall back to the text type instead.

Because the built-in text type of PostgreSQL does not support NULL bytes, the object type will result in unserialization errors. A workaround to this problem is to serialize()/unserialize() and base64_encode()/base64_decode() PHP objects and store them into a text field manually.

Let's look at a possible XML mapping for the Product Entity by using the object type:

<?xml version="1.0" encoding="utf-8"?>
<doctrine-mapping
xmlns="http://doctrine-project.org/schemas/orm/doctrine-mapping"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://doctrine-project.org/schemas/orm/doctrine-mapping
https://raw.github.com/doctrine/doctrine2/master/doctrine-mapping.xsd">

<entity
name="Product"
table="products">

<id
name="id"
column="id"
type="string"
length="255">
<generator strategy="NONE">
</generator>
</id>
<field
name="name"
type="string"
length="255"
/>
<field
name="price"
type="object"
/>
</entity>
</doctrine-mapping>

The key addition is type="object", which tells Doctrine that we're going to be using an object mapping. Let's see how we could create and persist a Product Entity using Doctrine:

// ... 
$em−>persist($product);
$em−>flush($product);

Let's check that if we now fetch our Product Entity from the database, it's returned in an expected state:

// ...
$repository = $em->getRepository('Ddd\Domain\Model\Product');
$item = $repository->find(1);
var_dump($item);

/*
class DddDomainModelProduct#177 (3) {
private $productId => int(1)
private $name => string(41) "Domain-Driven Design in PHP"
private $money => class DddDomainModelMoney#174 (2) {
private $amount => string(3) "100"
private $currency => class DddDomainModelCurrency#175 (1){
private $isoCode => string(3) "USD"
}
}
}
* /

Last but not least, the Doctrine DBAL 2 Documentation states that:

Object types are compared by reference, not by value. Doctrine updates this value if the reference changes and therefore behaves as if these objects are immutable value objects.

This approach suffers from the same refactoring issues as the Ad hoc ORM did. The object mapping type is internally using serialize/unserialize. What about instead using our own serialization?

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset