Creating a custom Doctrine DBAL type the right way

Today one of my colleague’s was debugging a strange issue with Doctrine’s schema validation tool which caused our test setup to fail (we’re running app/console doctrine:schema:validate as part of our CI process). The output was the same every time:

We quickly discovered the issue was caused by the custom UUID Doctrine DBAL type we introduced lately. This type was based on some gist we found on the web:

It turned out that doing a doctrine:schema:update kept executing the same update query over and over again:

One hour of debugging later I discovered the issue originated to MySqlSchemaManager::_getPortableTableColumnDefinition where a MySQL column gets reverse-engineered into a Doctrine\DBAL\Types\Type which is used in the schema comparison tool. We’re storing the UUID in a BINARY(16) field which results in a BinaryType after reverse-engineering because Doctrine can’t tell the difference between a BinaryType and UuidType because both result in the exact same MySQL column definition. However, there is a solution to fix this.

Using DC2Type in the comment

The solution is to add a comment to the field to store the metadata in. This seems to be missing in the docs but I’ve found some JIRA issue describing the feature. We have to change our column definition so the metadata of the type doesn’t get lost:

The corrected UuidType looks as following:

Unfortunately the binary type is always reverse-engineered with $fixed = true so you have to configure the UuidType accordingly (note the options) on your entities (haven’t found a better way yet):

This comment stuff in Doctrine is not well-documented and probably a lot of people experienced the same behaviour in the schema tool so I hope I prevented some nasty debug sessions in Doctrine’s core (although you learn a lot from it).