2016-07-14 11 views
0

Das Problem, mit dem ich konfrontiert bin, ist, dass ich Doktrin nicht zwingen kann, neue IDs für neue Objekte auszugeben. Zum Beispiel:Lehre: Wie IDs einzigartig halten?

/** 
* Something 
* 
* @ORM\Table(name="something") 
* @ORM\Entity 
*/ 
class Something 
{ 
    /** 
    * @var integer 
    * 
    * @ORM\Column(name="id", type="integer", nullable=false) 
    * @ORM\Id 
    * @ORM\GeneratedValue(strategy="IDENTITY") 
    */ 
    protected $id; 
} 

werden eindeutige IDs erzeugen offensichtlich - aber wenn das Objekt später gelöscht wird, wird die ID für einen späteren erzeugten Objekt verwendet werden. Das ist bedauerlich, da es Links geben kann, die sich auf diese ID beziehen, die jetzt auf falsche Objekte zeigen und nicht nur versagen.

Bei der Arbeit ohne Doktrin direkt auf der Datenbank, ich war autoincrement und es funktionierte wie erwartet. Mit Doktrin, um die Tabellen zu verwalten, scheint dies jedoch nicht zu funktionieren.

Die Verwendung von strategy="UUID" ist hilfreich und oft die bessere Wahl, aber manchmal ist dies nicht machbar. Beispielsweise scheint sich das Bundle FOSUserBundle auf Integer für die ID des Benutzers zu verlassen. Das bedeutet im Wesentlichen: a) Löschen Sie niemals Benutzer, sondern deaktivieren Sie sie einfach, oder b) fügen Sie eine weitere ID/einen anderen Schlüssel hinzu (ziemlich hacky, damit sich die Beziehungen auf diese künstliche ID verlassen).

Ist es möglich, neue ganzzahlige IDs zu erzwingen? (A Weg FOSBundle Verwendung UUID anstatt zu machen wäre schön, aber ich glaube nicht, das ist in Reichweite.)

Derzeit Lehre 2.5.4 mit SQLite innerhalb symfony mit 3.1.2 auf OS X - aber Produktionsserver wird Linux-basiert sein. Läuft auf PHP 7.0.

Antwort

1

Doktrin sollte GeneratedValue(strategy="IDENTITY") bis AUTOINCREMENT auf SQLite-Datenbanken nach Doctrine documentation zuordnen, so sollte es keinen Unterschied zu Ihren Versuchen ohne Lehre geben.

In der Tat sollten Identitätsspalten mit AUTOINCREMENT eine generierte Nummer nur dann erneut verwenden, wenn eine Transaktion, die sie generiert hat, zurückgesetzt wird (siehe https://sqlite.org/autoinc.html). In einem solchen Fall sollte die Nummer nicht in anderen Einträgen verwendet werden, da sie ebenfalls zurückgesetzt werden sollten.

So sehe ich kein Problem bei der Verwendung GeneratedValue(strategy="IDENTITY"), zumindest wenn Sie Transaktionen verwenden.

EDIT

Es gibt eine bug in Doctrine2, die richtig GeneratedValue(strategy="IDENTITY") von der Arbeit verhindert, aber a workaround existiert, die eine EventSubscriber für onSchemaCreateTable Ereignis registriert. Es erstellt die korrekte SQL, um die Tabelle mit AUTOINCREMENT Attribut in der Primärschlüsselspalte zu generieren.

+0

Das ist, was ich dachte - es wird einfach nicht hinzugefügt. Ich könnte wahrscheinlich die Tabelle manuell ändern, aber nach dem Ausführen der Doktrin: Schema: Update zu einem späteren Zeitpunkt, wird es wieder verworfen. :/ – Eiko

+0

Ich habe gerade in den Doktrin2-Code geschaut und vor allem in /vendor/doctrine/dbal/lib/Doctrine/DBAL/Platforms/SqlitePlatform.php - es scheint wirklich, dass 'strategie =" IDENTITY "' keine macht Die Verwendung der 'AUTOINCREMENT'-Funktion von sqlite im Gegensatz zur Doctrine-Dokumentation ... scheint ein Fehler in sqlite zu sein. –

+0

Es gibt bereits ein Problem in GitHub: https://github.com/doctrine/dbal/issues/2426 –