Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Doctrine custom type always altering table

I have added a custom type like:

namespace My\SuperBundle\Types;

use Doctrine\DBAL\Types\Type;
use Doctrine\DBAL\Platforms\AbstractPlatform;

class Money extends Type
{
    const MONEY = 'money';

    public function getSqlDeclaration(
        array $fieldDeclaration,
        AbstractPlatform $platform
    ) {
        return 'DECIMAL(10,2)';
    }

    public function getName()
    {
        return self::MONEY;
    }
}

And in my application boot:

namespace My\SuperBundle;

use Doctrine\DBAL\Types\Type;
use My\SuperBundle\Types\Money;

class MyBSuperBundle extends Bundle
{
    public function boot()
    {
        //add custom quantity and wight types
        $em = $this->container->get('doctrine.orm.entity_manager');

        if(!Type::hasType(Money::MONEY)) {
            Type::addType(Money::MONEY, 'My\SuperBundle\Types\Money');
        }
    }
}

However every time I update the database with:

php app/console doctrine:schema:update --dump-sql

I keep getting the following:

ALTER TABLE product_price CHANGE price price DECIMAL(10,2) DEFAULT NULL

Apart from that everything works super fine. The fields in the DB are correct. Is there a reason why doctrine keeps updating with the same data?

like image 495
mentalic Avatar asked Mar 27 '13 14:03

mentalic


4 Answers

You have to override the method requiresSQLCommentHint(AbstractPlatform $platform) and return true. Like that, doctrine will remember the custom type.

namespace My\SuperBundle\Types;

use Doctrine\DBAL\Types\Type;
use Doctrine\DBAL\Platforms\AbstractPlatform;

class Money extends Type
{
    const MONEY = 'money';

    public function getSqlDeclaration(
        array $fieldDeclaration,
        AbstractPlatform $platform
    ) {
        return 'DECIMAL(10,2)';
    }

    public function getName()
    {
        return self::MONEY;
    }

    /**
     * @inheritdoc
     */
    public function requiresSQLCommentHint(AbstractPlatform $platform)
    {
        return true;
    }
}

Source: Use column comments for further Doctrine Type Inference

like image 94
Kevin Robatel Avatar answered Nov 17 '22 00:11

Kevin Robatel


There's an alternative way to do this using configurations.

config.yml:

doctrine:
    dbal:
        types: { money: My\SuperBundle\Types\Money }

    connections:
        your_connection_name:
            mapping_types: { money: money }

Sources:

  • http://symfony.com/doc/current/cookbook/doctrine/dbal.html#registering-custom-mapping-types
  • https://github.com/sonata-project/SonataUserBundle/issues/103#issuecomment-10083314
like image 35
dmccabe Avatar answered Nov 16 '22 23:11

dmccabe


You are not telling the DBAL platform about your type, so obviously, the DBAL schema introspection utilities cannot recognize it. To register the type, you can do following:

use Doctrine\DBAL\Types\Type;
use My\SuperBundle\Types\Money;

class MyBSuperBundle extends Bundle
{
    public function boot()
    {
        /* @var $em \Doctrine\ORM\EntityManager */
        $entityManager = $this->container->get('doctrine.orm.entity_manager');

        if( ! Type::hasType(Money::MONEY)) {
            Type::addType(Money::MONEY, 'My\SuperBundle\Types\Money');
            $entityManager
                ->getConnection()
                ->getDatabasePlatform()
                ->registerDoctrineTypeMapping('decimal', Money::MONEY);
        }
    }
}

This should stop the DBAL from complaining about schema differences.

like image 30
Ocramius Avatar answered Nov 17 '22 00:11

Ocramius


I had the same problem with ZF2.

I solved it removing the hyphen in my custom type name.

Wrong:

'doctrine_type_mappings' => [
    'custom-type' => 'custom-type'
],

Good:

'doctrine_type_mappings' => [
    'customtype' => 'customtype'
],

More details about implementation in Zend Framework 2: https://github.com/doctrine/DoctrineORMModule/blob/master/docs/EXTRAS_ORM.md

I hope this can help someone.

like image 1
jawira Avatar answered Nov 17 '22 00:11

jawira