2 minutes
When to Use Embeddables or Custom Mapping Types in Doctrine
If you apply DDD in a Symfony project you’ll need to store value objects using Doctrine. We have two options to do that, using embeddables or using custom types, let’s see when we should use one or the other.
Embeddables
Embeddables are ideal for simple value objects that are formed by scalar types.
An important constraint is that they can’t be nullable in Doctrine 2 (probably will be in Doctrine 3) so this could key to decide between embeddables or custom types.
Following the example used in the official documentation if we have a VO like could be Address
that is form by: street
, postalCode
, city
and country
, all of them as simple strings.
/** @Entity */
class User
{
/** @Embedded(class = "Address") */
private $address;
}
/** @Embeddable */
class Address
{
/** @Column(type = "string") */
private $street;
/** @Column(type = "string") */
private $postalCode;
/** @Column(type = "string") */
private $city;
/** @Column(type = "string") */
private $country;
}
Custom Mapping Types
Custom mapping types are meant to be used when you want to do special stuff when reading from the database or when you want to store it to the database itself.
Following the previous example let’s imagine we want to have some logic to serialize the data inside the VO so we could do something like that:
namespace App\Module\Address\Infrastructure\Persistence\Doctrine;
use Doctrine\DBAL\Types\Type;
use Doctrine\DBAL\Platforms\AbstractPlatform;
use App\Module\Address\Domain\Address;
class AddressType extends Type
{
const TYPE = 'address';
public function convertToPHPValue($value, AbstractPlatform $platform)
{
return Address::fromString($value);
}
/**
* @param Address $value
*/
public function convertToDatabaseValue($value, AbstractPlatform $platform)
{
return $value->toString();
}
public function getSQLDeclaration(array $field, AbstractPlatform $platform)
{
return $platform->getJsonTypeDeclarationSQL($field);
}
public function getName()
{
return self::TYPE;
}
}
Check the official documentation here.