2017-02-04 1 views
0

Ich möchte eine ID mit Präfix definieren.Doctrine Custom ID mit automatischer Erhöhung

Zum Beispiel für einen Auftrag Unternehmen seine „OR17000001“ In diesem Beispiel wird das Präfix „OR17“

So habe ich so meine id Entitäten deklarieren:

/** 
* @var string 
* 
* @ORM\Column(name="id", type="string", length=8) 
* @ORM\Id 
* @ORM\GeneratedValue(strategy="CUSTOM") 
* @ORM\CustomIdGenerator(class="My\Bundle\Generator\OrderCodeGenerator") 
*/ 
private $id; 

Und mein Generator ist:

<?php 

namespace My\Bundle\Generator; 

use Doctrine\ORM\Id\AbstractIdGenerator; 
use Doctrine\ORM\EntityManager;  
use My\Bundle\Entity\Order; 

class OrderCodeGenerator extends AbstractIdGenerator 
{ 
    /** 
     * Format : 
    * $prefix - string 
    * $year - take 2 first letters (17) 
    * $increment - Take the last code + 1 
    * 
    * @param EntityManager $em 
    * @param \Doctrine\ORM\Mapping\Entity $entity 
    * @return bool|string 
    */ 
    public function generate(EntityManager $em, $entity) 
    { 
     if ($entity instanceof Order) { 
      $now = new \DateTime(); 
      $year = $now->format('y'); 
      $prefix = 'OR'; 

      $maxCode = $em->getRepository('MyRepo:Order')->findMaxCode($year, $prefix); 

      if ($maxCode) { 
       $increment = substr($maxCode[1], -4); 
       $increment = (int)$increment + 1; 
      } else 
       $increment = 0; 

      $code = $prefix . $year . sprintf('%04d', $increment); 
      return $code; 
     } 

     return false; 
    } 
} 

Ohne die Methode findMaxCode vergessen:

public function findMaxCode($year, $prefix) 
{ 
    $qb = $this->createQueryBuilder('entity'); 

    $qb->where($qb->expr()->like('entity.id', ':code')) 
     ->setParameter('code', '%' . $prefix . $year . '%'); 

    $qb->select($qb->expr()->max('entity.id')); 

    return $qb->getQuery()->getOneOrNullResult(); 
} 

, dass die Arbeit in Ordnung =)

Mein Problem ist, wenn ich versuche, einige Einheiten in der gleichen Zeit hinzuzufügen. Mein Fall ist:

  • Bestellen Einheit mit einigen Elementen (es ist eine Form Sammlung)
  • Artikel Einheit

Also ich brauche, um benutzerdefinierte ID des Artikels mit dieser Strategie bestellen. Und das Problem ist für den maximalen Code gefunden. Ich habe diesen Fehler:

SQLSTATE [23000]: Integrität Einschränkungsverletzung: 1062 DUPLICATA du champ '' IT170000001 pour la clef 'primären'

der Generator nicht die maximale Code gefunden für erzeuge den zweiten Gegenstand, weil es keinen Flush gibt.

Wie kann ich den Inkrementwert zwischen 2 id Generation vor dem Flush speichern ??


Lösung:

Ich halte numerische ID für meine Artikel. Es ist nützlich für meine Order-Entity, es ist besser lesbar als ein einfacher Int. Aber ich interessiere mich nicht für Item.

Thx zu Honza Rydrych

Antwort

2

Querying DB für die letzte ID eingeführt und dann auf "+ Eins" eingefügt ist keine zuverlässige Lösung. Meine Lösung für diesen Fall wäre Lehre IDs auf dem üblichen Weg generieren und fügen Sie das Präfix "OR/Year /", wenn Sie die Daten präsentieren müssen.

(Fakultativ können Sie schreiben, benutzerdefinierte Zweig Erweiterung für die Präsentation der ID http://symfony.com/doc/current/templating/twig_extension.html)

+0

Thx für Ihre Antwort, was ist es, die Grenze einer numerischen ID ?? Ich habe Angst darüber, ich kann ~ 10 000 Elemente/Jahr haben – Quovandius

+0

Ich weiß nicht, welchen RDBM-Server Sie verwenden, aber wie ich in Lehre/MySQL weiß, verwendet Int (11) als Standard-ID Feldtyp (max Wert ist 2147483647 signiert), also hast du mehr als 200-tausende Jahre :-) –

+0

Ok thx für deine Tipps. Ich habe es nicht geschrieben, ich benutze auch Mysql. Ich suche weiter in welchem ​​Fall kann ich benutzerdefinierte Strategie-ID verwenden, ich habe keine Ahnung ^^ – Quovandius

Verwandte Themen