Holen Sie sich die letzte Insert-ID mit Doktrin 2?

76

Wie kann ich die letzte Insert-ID mit Doctrine 2 ORM erhalten? Ich habe das nicht in der Dokumentation der Lehre gefunden, ist das überhaupt möglich?

Tom
quelle
Versuchen Sie dies, geben Sie am Ende Ihrer Einfügung die ID zurück ... wie return $ this-> id;
Manie

Antworten:

178

Ich musste dies nach dem Flush verwenden, um die letzte Insert-ID zu erhalten:

$em->persist($user);
$em->flush();
$user->getId();
Tom
quelle
2
Kann es nicht benutzen. Fehler erhalten Aufruf der undefinierten Methode Test \ Entity \ Test :: getId () in "Mein Projekt"
noobie-php
@ noobie-php Sie müssen einen öffentlichen Getter für Ihre ID definieren (wenn dieser privat ist, wie es sein sollte)
cheesemacfly
@cheesemacfly: Ich habe dies bereits behoben. Dieser Fehler wird (in meinem Szenario) generiert, wenn wir Flush () aus irgendeinem Grund nicht ausführen können. Sobald Flush () erfolgreich ausgeführt wurde, funktioniert getID (), vorausgesetzt, Getter und Setter sind kein Problem hier
noobie-php
1
Was ist, wenn ich persist()die Entität in einer Schleife und flush()danach? Ich versuche das herauszufinden, aber bisher kein Glück.
Nat Naydenova
codeWeisen Sie der Variablen eine ID zu: $ id = $ user-> getId (); code
Josiah
40

Sie können auf die ID zugreifen, nachdem Sie die persist-Methode des Entitätsmanagers aufgerufen haben.

$widgetEntity = new WidgetEntity();
$entityManager->persist($widgetEntity);
$entityManager->flush();
$widgetEntity->getId();

Sie tun , um zu spülen müssen diese ID zu bekommen.

Syntaxfehlerbehebung: Semikolon hinzugefügt, nachdem $ entityManager-> flush () aufgerufen wurde.

Clarkstachio
quelle
6
Ich musste spülen, um den Wert zurückzubekommen. Das Fortbestehen war nicht genug, da die Elemente erst nach dem Leeren in die Datenbank geschrieben werden.
Jeremy Hicks
29

Wenn Sie keine Entitäten verwenden, sondern Native SQL, wie hier gezeigt , möchten Sie möglicherweise die zuletzt eingefügte ID wie unten gezeigt erhalten:

$entityManager->getConnection()->lastInsertId()

Bei Datenbanken mit Sequenzen wie PostgreSQL beachten Sie bitte, dass Sie den Sequenznamen als ersten Parameter der lastInsertIdMethode angeben können.

$entityManager->getConnection()->lastInsertId($seqName = 'my_sequence')

Weitere Informationen finden Sie hier und hier im Code auf GitHub .

Francesco Casula
quelle
Dies funktioniert möglicherweise nicht mit jedem DBMS. Zum Beispiel funktioniert es nicht mit Postgres (wegen der Sequenzen)
paul.ago
Genial!! Ich habe stundenlang nach diesem kleinen Ausschnitt gesucht.
MikeGA
4
@ paul.ago Sie müssen nur den Namen der Sequenz kennen, zB:lastInsertId('articles_id_seq')
ChocoDeveloper
1
Sie können den Namen der Sequenz auch folgendermaßen erhalten: $conn = $this->getDoctrine()->getConnection(); $metadata = $em->getClassMetadata('\App\Entity\YourClass'); $seqName = $metadata->getSequenceName($conn->getDatabasePlatform());Works :-)
Hugues D
10

Das Aufrufen von flush () kann möglicherweise viele neue Entitäten hinzufügen, sodass der Begriff "lastInsertId" nicht wirklich verwendet wird. Doctrine füllt jedoch die Identitätsfelder immer dann aus, wenn eines generiert wird. Daher enthält der Zugriff auf das ID-Feld nach dem Aufruf von flush immer die ID einer neu "persistierten" Entität.

beberlei
quelle
2

Ein bisschen spät, um die Frage zu beantworten. Aber,

Wenn es sich um eine MySQL-Datenbank handelt

sollte $doctrine_record_object->idfunktionieren, wenn AUTO_INCREMENTin der Datenbank und in Ihrer Tabellendefinition definiert ist.

Purasapa
quelle
0

Hier poste ich meinen Code, nachdem ich mich einen Arbeitstag lang bemüht habe, diese Lösung zu finden.

Funktion zum Abrufen des zuletzt gespeicherten Datensatzes:

private function getLastId($query) {
        $conn = $this->getDoctrine()->getConnection();
        $stmt = $conn->prepare($query);
        $stmt->execute();
        $lastId = $stmt->fetch()['id'];
        return $lastId;
    }

Eine weitere Funktion, die die obige Funktion aufruft

private function clientNum() {
        $lastId = $this->getLastId("SELECT id FROM client ORDER BY id DESC LIMIT 1");
        $noClient = 'C' . sprintf("%06d", $lastId + 1); // C000002 if the last record ID is 1
        return $noClient;
    }
Techappri
quelle
0

Einfacher: SELECT max(id) FROM client

Olivier Bussier
quelle