Xavi
Xavi

Reputation: 1585

Doctrine2 - Get entity ID before flush

Is there any way to get an entity ID before the persist/flush? I mean:

$entity = new PointData();
$form   = $this->createForm(new PointDataType(), $entity);

If I try $entity->getId() at this point, it returns nothing.

I can get it working by:

$em->persist($entity);
$em->flush();

(supposing $em = $this->getDoctrine()->getEntityManager();)

How can I achieve this?

Upvotes: 21

Views: 32899

Answers (6)

elier
elier

Reputation: 459

You can use the @PostPersist annotation. A method annotated with it will be executed just before the flush ends and the entity Id is already available.

https://www.doctrine-project.org/projects/doctrine-orm/en/2.6/reference/events.html

postPersist - The postPersist event occurs for an entity after the entity has been made persistent. It will be invoked after the database insert operations. Generated primary key values are available in the postPersist event.

<?php

use Doctrine\ORM\Mapping as ORM;

/** 
 * @ORM\Entity 
 * @ORM\HasLifecycleCallbacks 
 */
class PointData
{
    /**
     * @ORM\Column(name="id", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
     private $id;

     ...

     /** 
      * @ORM\PostPersist 
      */
     public function onPostPersist()
     {
         // Put some simple logic here that required the auto-generated Id.

         $this->doSomething($this->id);
     }
    
     ...

}

Upvotes: 12

SpicyTacos23
SpicyTacos23

Reputation: 550

Not sure why you need the ID before flushing, but, if you really need to persist the entity without saving to the database you can try using Transactions.

Try something like this:

$em->beginTransaction();
$em->persist($entity);
$em->flush();
$id = $entity->getId();
//do some stuff and save when ready
$em->commit();

Upvotes: 0

ProMix
ProMix

Reputation: 27

$em = $this->getDoctrine()->getManager();
$entity = new PointData();

$em->persist($entity);

$entity->getId() <-- return <int>

$em->flush();

after persist you can get id

Upvotes: -2

mohamed abohassan
mohamed abohassan

Reputation: 9

Doctrine best practices says,

You should avoid auto-generated identifiers. because:

  • Your DB operations will block each other
  • You are denying bulk inserts
  • You cannot make multi-request transactions
  • Your object is invalid until saved
  • Your object does not work without the DB

So you can use UUIDS instead

public function __construct() {
     $this->id = Uuid::uuid4();  
}

Also, Doctrine supports the UUID generation strategy since version 2.3.

Upvotes: 0

achref akrouti
achref akrouti

Reputation: 655

you can use an auto generate ID to get a key like universally unique identifiers (UUID) or you can take the events of symfony: postFlush - The postFlush event occurs at the end of a flush operation.

Upvotes: 0

timdev
timdev

Reputation: 62914

If you want to know the ID of an entity before it's been persisted to the database, then you obviously can't use generated identifiers. You'll need to find some way to generate unique identifiers yourself (perhaps some kind of hash function can produce unique-enough values).

This is rarely a good idea, though, so you should be careful.

I would think very carefully about why I need to know the identifier before flush. Doctrine is quite good at letting you build up a big object graph, and persist/flush it all at once. It seems likely that you've got something ugly in your architecture that you're trying to work around. It might be a good idea to review that before going down the application-generated-id route.

Upvotes: 35

Related Questions