简体   繁体   中英

Doctrine2 custom type not working like primary key Symfony2

I wanna make primary key based on UUID and storage in binary(16).

For this purpose I create new type for Doctrine - "binary"

 class BinaryType extends Type
{
const BINARY = 'binary';

public function getSqlDeclaration(array $fieldDeclaration, AbstractPlatform $platform)
{
    return sprintf('BINARY(%d)', $fieldDeclaration['length']);
}

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

public function convertToPhpValue($value, AbstractPlatform $platform)
{

    if ($value !== null) {
        $value= unpack('H*', $value);
        return array_shift($value);
    }
}

public function convertToDatabaseValue($value, AbstractPlatform $platform)
{
    if ($value !== null) {
        return pack('H*', $value);
    }
}

}

Also register this type:

class MyBundle extends Bundle
{
  public function boot()
  {
     Type::addType('binary', '...\Doctrine2\BinaryType');
  }
}

Question: Why this type working good in a simple fields, but not working with primary key (field where annotation @ORM\\Id), field just not appear.

Example not working annotation. In this case not appear any row from db:

/**
 * @ORM\Id
 * @ORM\Column(type="binary", length=16, name="id", nullable=false)
 *
 * @ORM\GeneratedValue(strategy="NONE")
 */
private $id;

 /**
 * 
 * @ORM\Column(name="second_id", type="integer", nullable=false)
 */
private $secondId;

Example of working annotation. We see rows from db and id in binary type:

/**
 * 
 * @ORM\Column(type="binary", length=16, name="id", nullable=false)
 * @ORM\GeneratedValue(strategy="NONE")
 */
private $id;

 /**
 * @ORM\Id
 * @ORM\Column(name="second_id", type="integer", nullable=false)
 */
private $secondId;

I spent a good few hours on this exact problem because I needed to do it as well. I ended up getting your exact code to work with one slight change: omitting the @ORM/GeneratedValue(strategy="NONE").

In other words if you change this

/**
 * @ORM\Id
 * @ORM\Column(type="binary", length=16, name="id", nullable=false)
 *
 * @ORM\GeneratedValue(strategy="NONE")
 */
private $id;

To this

/**
 * @ORM\Id
 * @ORM\Column(type="binary", length=16, name="id", nullable=false)
 */
private $id;

it worked for me.

One more thing if you want to have id generation you must implement your own generator like:

use Doctrine\ORM\EntityManager;
use Doctrine\ORM\Id\AbstractIdGenerator;

class GuidGenerator extends AbstractIdGenerator
{
    public function generate(EntityManager $em, $entity)
    {
        //return generated id
    }
}

and change your annotation to

/**
 * @ORM\Id
 * @ORM\Column(type="binary", length=16, name="id", nullable=false)
 * @ORM\GeneratedValue(strategy="CUSTOM") 
 * @ORM\CustomIdGenerator(class="path\to\IDGenerators\GuidGenerator") 
 */
private $id;

I realize you probably moved on but just posting this for the next person.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM