* If X is a preexisting managed entity, it is ignored by the persist operation. However, the persist operation is cascaded to entities referenced by X, if the relationships from X to these other entities are mapped with cascade=PERSIST or cascade=ALL (see "Transitive Persistence").
An entity can be removed from persistent storage by passing it to the `EntityManager#remove($entity)` method. By applying the `remove` operation on some entity, that entity becomes REMOVED, which means that its persistent state will be deleted once `EntityManager#flush()` is invoked.
> Just like `persist`, invoking `remove` on an entity does NOT cause an immediate SQL
> DELETE to be issued on the database. The entity will be deleted on the next invocation
> of `EntityManager#flush()` that involves that entity.
Example:
[php]
$em->remove($user);
$em->flush();
The semantics of the remove operation, applied to an entity X are as follows:
* If X is a new entity, it is ignored by the remove operation. However, the remove operation is cascaded to entities referenced by X, if the relationship from X to these other entities is mapped with cascade=REMOVE or cascade=ALL (see "Transitive Persistence").
* If X is a managed entity, the remove operation causes it to become removed. The remove operation is cascaded to entities referenced by X, if the relationships from X to these other entities is mapped with cascade=REMOVE or cascade=ALL (see "Transitive Persistence").
* If X is a detached entity, an InvalidArgumentException will be thrown.
* If X is a removed entity, it is ignored by the remove operation.
An entity is detached from an EntityManager and thus no longer managed by
invoking the `EntityManager#detach($entity)` method on it or by cascading
the detach operation to it. Changes made to the detached entity, if any
(including removal of the entity), will not be synchronized to the database
after the entity has been detached.
Doctrine will not hold on to any references to a detached entity.
Example:
[php]
$em->detach($entity);
The semantics of the detach operation, applied to an entity X are as follows:
* If X is a managed entity, the detach operation causes it to become detached. The detach operation is cascaded to entities referenced by X, if the relationships from X to these other entities is mapped with cascade=DETACH or cascade=ALL (see "Transitive Persistence"). Entities which previously referenced X will continue to reference X.
* If X is a new or detached entity, it is ignored by the detach operation.
* If X is a removed entity, the detach operation is cascaded to entities referenced by X, if the relationships from X to these other entities is mapped with cascade=DETACH or cascade=ALL (see "Transitive Persistence"). Entities which previously referenced X will continue to reference X.
There are several situations in which an entity is detached automatically without invoking the `detach` method:
* When `EntityManager#clear()` is invoked, all entities that are currently managed by the EntityManager instance become detached.
* When serializing an entity. The entity retrieved upon subsequent unserialization will be detached (This is the case for all entities that are serialized and stored in some cache, i.e. when using the Query Result Cache).
The `detach` operation is usually not as frequently needed and used as `persist` and `remove`.
++ Merging entities
Merging entities refers to the merging of (usually detached) entities into the
context of an EntityManager so that they become managed again. To merge the
state of an entity into an EntityManager use the `EntityManager#merge($entity)`
method. The state of the passed entity will be merged into a managed copy of
this entity and this copy will subsequently be returned.
Example:
[php]
$detachedEntity = unserialize($serializedEntity); // some detached entity
$entity = $em->merge($detachedEntity);
// $entity now refers to the fully managed copy returned by the merge operation.
// The EntityManager $em now manages the persistence of $entity as usual.
* If X is a removed entity instance, an InvalidArgumentException will be thrown.
* If X is a managed entity, it is ignored by the merge operation, however, the merge operation is cascaded to entities referenced by relationships from X if these relationships have been mapped with the cascade element value MERGE or ALL (see "Transitive Persistence").
* For all entities Y referenced by relationships from X having the cascade element value
MERGE or ALL, Y is merged recursively as Y'. For all such Y referenced by X, X' is set to reference Y'. (Note that if X is managed then X is the same object as X'.)
* If X is an entity merged to X', with a reference to another entity Y, where cascade=MERGE or cascade=ALL is not specified, then navigation of the same association from X' yields a reference to a managed object Y' with the same persistent identity as Y.
The `merge` operation will throw an `OptimisticLockException` if the entity
being merged uses optimistic locking through a version field and the versions
Doctrine 2 provides the following ways, in increasing level of power and flexibility, to query for persistent objects. You should always start with the simplest one that suits your needs.
+++ By Primary Key
The most basic way to query for a persistent object is by its identifier / primary key using the `EntityManager#find($entityName, $id)` method. Here is an example:
[php]
// $em instanceof EntityManager
$user = $em->find('MyProject\Domain\User', $id);
The return value is either the found entity instance or null if no instance could be found with the given identifier.
Essentially, `EntityManager#find()` is just a shortcut for the following:
`EntityManager#getRepository($entityName)` returns a repository object which provides many ways to retrieve entities of the specified type. By default, the repository instance is of type `Doctrine\ORM\EntityRepository`. You can also use custom repository classes as shown later.
To query for one or more entities based on several conditions that form a logical conjunction, use the `findBy` and `findOneBy` methods on a repository as follows:
Whenever you query for an entity that has persistent associations and these associations are mapped as EAGER, they will automatically be loaded together with the entity being queried and is thus immediately available to your application.
+++ By Lazy Loading
Whenever you have a managed entity instance at hand, you can traverse and use any associations of that entity that are configured LAZY as if they were in-memory already. Doctrine will automatically load the associated objects on demand through the concept of lazy-loading.
+++ By DQL
The most powerful and flexible method to query for persistent objects is the Doctrine Query Language, an object query language. DQL enables you to query for persistent objects in the language of objects. DQL understands classes, fields, inheritance and associations.
A DQL query is represented by an instance of the `Doctrine\ORM\Query` class. You create a query using `EntityManager#createQuery($dql)`. Here is a simple example:
[php]
// $em instanceof EntityManager
// All users with an age between 20 and 30 (inclusive).
$q = $em->createQuery("select u from MyDomain\Model\User u where u.age >= 20 and u.age <= 30");
$users = $q->getResult();
Note that this query contains no knowledge about the relational schema, only about the object model. DQL supports positional as well as named parameters, many functions, (fetch) joins, aggregates, subqueries and much more. Detailed information about DQL and its syntax as well as the Doctrine\ORM\Query class can be found in [the dedicated chapter](http://www.doctrine-project.org/documentation/manual/2_0/en/dql-doctrine-query-language). For programmatically building up queries based on conditions that are only known at runtime, Doctrine provides the special `Doctrine\ORM\QueryBuilder` class. More information on constructing queries with a QueryBuilder can be found [in the dedicated chapter](http://www.doctrine-project.org/documentation/manual/2_0/en/query-builder).
+++ By Native Queries
As an alternative to DQL or as a fallback for special SQL statements native queries can be used.
Native queries are built by using a hand-crafted SQL query and a ResultSetMapping that describes
how the SQL result set should be transformed by Doctrine. More information about native queries
can be found in [the dedicated chapter](http://www.doctrine-project.org/documentation/manual/2_0/en/native-sql).
+++ Custom Repositories
By default the EntityManager returns a default implementation of `Doctrine\ORM\EntityRepository` when
you call `EntityManager#getRepository($entityClass)`. You can overwrite this behaviour by specifying
the class name of your own Entity Repository in the Annotation, XML or YAML metadata.
In large applications that require lots of specialized DQL queries using a custom repository is
one recommended way of grouping these queries in a central location.