Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How does doctrine entity manager flush() method works?

In the Doctrine documentation there is this code:

<?php
// update_product.php <id> <new-name>
require_once "bootstrap.php";

$id = $argv[1];
$newName = $argv[2];

$product = $entityManager->find('Product', $id);

if ($product === null) {
    echo "Product $id does not exist.\n";
    exit(1);
}

$product->setName($newName);

$entityManager->flush();

What I don't understand is the last part, where, after setting the product name with $product->setName(), the $entityManager->flush() method is called:

$product->setName($newName);
$entityManager->flush();

It seems to me that there is no connection between the $product variable and the $entityManager variable, except for the fact that $product should contain the response from the $entityManager->find() method.

How is it possible that $entityManager->flush() can read values set by $product->setName()?

like image 984
Aerendir Avatar asked Jan 22 '15 20:01

Aerendir


2 Answers

It's a ORM magic :)

But if seriously, when you fetch your data using Doctrine, it added to your objects a lot of metadata. You can look at these fields by yourself just var_dump() an object.

When you make flush(), Doctrine checks all the fields of all fetched data and make a transaction to the database.

When you initialize a new object, it doesn't have any Doctrine metadata, so you have to call one more method persist() to add it.

Also you can just look at the source code of EntityManager to better understand how it works — Doctrine is an opensource project.

like image 92
chapay Avatar answered Oct 25 '22 16:10

chapay


Doctrine uses the Identity Map pattern to track objects. Whenever you fetch an object from the database, Doctrine will keep a reference to this object inside its UnitOfWork. The array holding all the entity references is two-levels deep and has the keys “root entity name” and “id”. Since Doctrine allows composite keys the id is a sorted, serialized version of all the key columns.

http://doctrine-orm.readthedocs.org/en/latest/reference/unitofwork.html

And you might ask how it can read/write the values to the entity, because, well, they are protected (they should if you are following the user guide)!

It's simple, Doctrine uses reflection.

Interesting method from the UnityOfWork which computes if there are any changes to the entities: https://github.com/doctrine/doctrine2/blob/master/lib/Doctrine/ORM/UnitOfWork.php#L560

like image 37
jonathancardoso Avatar answered Oct 25 '22 15:10

jonathancardoso