Symfony2 / Doctrine2 - Check Entity Object is new, never persisted

4.6k views Asked by At

Short and easy question:

How to determine that Doctrine PHP Entity Object is new?

New - I mean is not in database and its not "update" action. Most important thing - I need way to check it without any query like:

$manager->findOne($something);

Actually sometimes I tried to check "is ID null" but Im not 100% sure this method is valid or not. And other tip or probably core of this question - I seen something like:

$manager->getUnitOfWork()->isInIdentityMap($object);

Looks nice but I can't find what actually do function isInIdentityMap. Is it true if it was persisted or removed? When this function say true and false?


//EDIT

I need to detect entity object created first time - existing only in php but not in database. Of course entity loaded from database to apply updates is not new for me - for example:

When you createing Comment object you need to increment commentCounter but it should be incremented only when you flushing this comment for first time. You don't want to increment it when you updating or deleting existing comment. How to check that comment is new and counter should be incremented.

Please explain in answers why your method is good/better

2

There are 2 answers

0
Griva On BEST ANSWER

I checked some docs and tested some things and I hope that everything I write is correct:

Method isInIdentityMap

$manager->getUnitOfWork()->isInIdentityMap($object);

is probably perfect for my case because it checks that my object exist in Identity Map, this map store only flushed objects or actually object with ID. New Object before persistence and after persist action still have NULL ID so its not in this map. This way as long as object was not flushed into database this method should work. (Map contains only objects loaded from database)

Method to check NULL ID

if($obj->getId() == null){
    //code
}

should work too, its very similar to first methid but still Im not 100% sure it always work as I want and in addition we have first method so... Its better to use function prepared for it.

Method contains

$entityManager->contains($entity)

Do job but for other case. This method checks objects in entity manager but any persisted object, scheduled for any action is already tracked by entityManager. This function can help only as long as object is not persisted.

Other methods

Unit of work have many other methods, I didnt check them all but it seems we can easly check many other things using functions like:

->scheduleForInsert();
->scheduleForUpdate();
// etc

And other case - using Doctrine events event:

prePersist 

prePersist - The prePersist event occurs for a given entity before the respective EntityManager persist operation for that entity is executed. It should be noted that this event is only triggered on initial persist of an entity (i.e. it does not trigger on future updates).

6
Pipe On

You can use

$entityManager->contains($entity)

Edit: Based on your edit, i suggest to use an entity listener: http://doctrine-orm.readthedocs.io/en/latest/reference/events.html#entity-listeners So you don't need to check if the entity is new or not in many parts in your application when an entity is persisted, you only setup the entity listener and it works wherever you create and persist the entities.