Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Generate unique id - doctrine - symfony2

I want to generate a unique ticket ID for my tickets. But how to let doctrine generate a unique id?

/**
 * @ORM\Column(name="id", type="integer")
 * @ORM\Id()
 * @ORM\GeneratedValue(strategy="AUTO")
 */
protected $id;

little more explain:

  • id must be 6 charters like: 678915
  • id must be unique
like image 796
Mitchel Verschoof Avatar asked Feb 23 '13 10:02

Mitchel Verschoof


4 Answers

As of version 2.3, you can just add the following annotations to your property:

/**
 * @ORM\Column(type="guid")
 * @ORM\Id
 * @ORM\GeneratedValue(strategy="UUID")
 */
protected $id;
like image 124
Jonathan Avatar answered Sep 22 '22 04:09

Jonathan


Use custom GeneratedValue strategy:

1. In your Entity class:

/**
 * @ORM\Id
 * @ORM\Column(type="integer")
 * @ORM\GeneratedValue(strategy="CUSTOM")
 * @ORM\CustomIdGenerator(class="AppBundle\Doctrine\RandomIdGenerator")
 */
protected $id;

2. Then create file AppBundle/Doctrine/RandomIdGenerator.php with content

namespace AppBundle\Doctrine;
use Doctrine\ORM\Id\AbstractIdGenerator;

class RandomIdGenerator extends AbstractIdGenerator
{
    public function generate(\Doctrine\ORM\EntityManager $em, $entity)
    {
        $entity_name = $em->getClassMetadata(get_class($entity))->getName();

        // Id must be 6 digits length, so range is 100000 - 999999
        $min_value = 100000;
        $max_value = 999999;

        $max_attempts = $min_value - $max_value;
        $attempt = 0;

        while (true) {
            $id = mt_rand($min_value, $max_value);
            $item = $em->find($entity_name, $id);

            // Look in scheduled entity insertions (persisted queue list), too
            if (!$item) {
                $persisted = $em->getUnitOfWork()->getScheduledEntityInsertions();
                $ids = array_map(function ($o) { return $o->getId(); }, $persisted);
                $item = array_search($id, $ids);
            }

            if (!$item) {
                return $id;
            }

            // Should we stop?
            $attempt++;
            if ($attempt > $max_attempts) {
                throw new \Exception('RandomIdGenerator worked hardly, but failed to generate unique ID :(');
            }  
        }

    }
}
like image 32
psylosss Avatar answered Sep 22 '22 04:09

psylosss


You can use the PrePersist annotation, like this:

/**
 * @ORM\PrePersist()
 */
public function preSave() {
    $this->id = uniqid();
}

As the annotation name suggest, it will be run before object persistence into database.

For unique id, I simply use a native php uniqid() function http://php.net/manual/en/function.uniqid.php which will return 13 characters. To get only 6 characters, refer to this PHP Ticket ID Generation

In the $id property, I think you also need to remove this line to prevent auto generated value of it:

@ORM\GeneratedValue(strategy="AUTO")
like image 38
ihsan Avatar answered Sep 23 '22 04:09

ihsan


Doctrine will treat this field as your primary key (because of the @Id annotation), so this field is already unique. If you have the @GeneratedValue annotation on AUTO strategy Doctrine will figure out which strategy to use dependend on the db platform. It will default to IDENTITY on MySql and the field will be a auto_increment then.

You can write the id annotation without the brackets as follows.

  • ORM\Id
like image 37
Bram Gerritsen Avatar answered Sep 22 '22 04:09

Bram Gerritsen