A free and open-source book on ZF3 for beginners

12.7. About Entity Manager

Entity manager is the primary access point to ORM functionality provided by Doctrine.

EntityManager is a Doctrine class that lives in Doctrine\ORM namespace and used to retrieve entities from their repositories using search criteria and save entities back to database.

EntityManager is registered as a service in the Zend Framework 3 service manager. In your factory class, you retrieve the EntityManager from service manager as follows (if you need a different connection than orm_default, just replace the orm_default with the required connection name):

// Get Doctrine entity manager
$entityManager = $container->get('doctrine.entitymanager.orm_default');   

The most used methods provided by the EntityManager class are listed in table 12.4 below.

Table 12.4. Methods of the EntityManager
Method Description
persist($entity) Places new entity into entity manager (makes it managed).
remove($entity) Removes an entity from database.
flush() Flushes all changes to objects that have been queued up to now to the database.
createQuery($dql) Creates a new Query object.
getRepository($entityName) Gets the repository for an entity class.

Let's review the methods from table 12.4.

To add a newly created entity to entity manager (to make the entity "managed"), you use entity manager's persist() method. To remove an entity from database, you use entity manager's remove() method.

When you call persist() or remove(), EntityManager remembers your changes in memory, but doesn't apply changes to database automatically (by performance reasons). To apply changes to database in a single transaction, you use the flush() method.

For example, look at the code example below that shows how to create an instance of the Post entity and save it to database:

// Create new Post entity.
$post = new Post();
$post->setTitle('Top 10+ Books about Zend Framework 3');
$post->setContent('Post body goes here');
$currentDate = date('Y-m-d H:i:s');

// Add the entity to entity manager.

// Apply changes to database.

The createQuery() method of the entity manager is designed for creating a query from a DQL string. It returns the Query object. You then execute the query and get results (an array of entities matching search conditions).

The getRepository() method of the entity manager is designed to get repository by entity class name. Please look below for example where we get the repository for our Post entity:

$repository = $entityManager->getRepository(Post::class);

12.7.1. Entity Repositories

Conceptually, each entity class has its own repository. The repository provides methods for retrieving entities from database. The repository can be considered as a collection of all available entities of certain class. For example, there are repositories for our Post, Comment, and Tag entities.

To load data from the database, you retrieve an entity from its repository. When you request the repository for an entity, it loads the data from the table mapped to the entity, and assigns entity's fields with the data.

The Doctrine\ORM\EntityRepository class implements the default repository. If needed, you can, by extending the EntityRepository, create your own repository for certain entity class. We will show how to do that later.

The most used methods provided by the EntityRepository class are listed in table 12.5.

Table 12.5. Methods of the EntityRepository
Method Description
findAll() Finds all entities in the repository.
find($id) Finds an entity by its identifier.
findBy($criteria, $orderBy, $limit, $offset) Finds entities by a set of criteria.
findOneBy($criteria, $orderBy) Finds a single entity by a set of criteria.
createQueryBuilder($alias) Creates a new QueryBuilder instance that is prepopulated for this entity name.

The findAll() method gets all entities from repository. For simple example of its usage, look below:

// Find all posts from repository
$posts = $entityManager->getRepository(Post::class)->findAll();

The find() method is the simplest method of searching for an entity. It retrieves an entity by its ID (primary key).

In the example below, we select post with ID = 1.

// Find post by primary key (ID)
$post = $entityManager->getRepository(Post::class)->find(1);

The findBy() takes a search criteria (and optional sorting order and limit) arguments and returns a collection of entities matching criteria. The findOneBy() method is very similar to findBy(), but it returns the first entity matching the criteria.

In the code example below, we use the findBy() method for selecting 50 most recent published posts:

// Find 50 most recent published posts
$posts = $entityManager->getRepository(Post::class)->findBy(
           ['dateCreated'=>'DESC'], 50);

For your convenience, the EntityRepository class also provides magic methods allowing you to query entities by attribute name with the findByX and findOneByX methods, as follows (just substitute the X placeholder with an attribute name):

// Query a single post by ID attribute
$post = $entityManager->getRepository(Post::class)->findOneById(1);

// Query posts by status attribute
$posts = $entityManager->getRepository(Post::class)

And the most complex search method is the createQueryBuilder(). That method allows to create complex DQL queries.

If standard find methods are not sufficient (or if you have complex search criteria and DQL queries), you can create your own repository by extending the standard EntityRepository class and encapsulate the search logic there. We will show how to do that later when implementing tag cloud feature for our Blog sample.