81 lines
5.0 KiB
Plaintext
81 lines
5.0 KiB
Plaintext
|
This chapter gives an overview of the overall architecture, terminology and constraints of
|
|||
|
Doctrine 2. It is recommended to read this chapter carefully.
|
|||
|
|
|||
|
++ Entities
|
|||
|
|
|||
|
An entity is a lightweight persistent domain object. An entity can be any regular
|
|||
|
php class that obeys to the following restrictions:
|
|||
|
|
|||
|
* An entity class must not be final or contain final methods.
|
|||
|
* An entity class must not implement `__clone` or [do so safely](http://www.doctrine-project.org/documentation/cookbook/2_0/en/implementing-wakeup-or-clone).
|
|||
|
* An entity class must not implement `__wakeup` or [do so safely](http://www.doctrine-project.org/documentation/cookbook/2_0/en/implementing-wakeup-or-clone).
|
|||
|
Also consider implementing [Serializable](http://de3.php.net/manual/en/class.serializable.php]) instead.
|
|||
|
* Any two entity classes in a class hierarchy that inherit directly or indirectly from one another must not have a mapped property with the same name.
|
|||
|
That is, if B inherits from A then B must not have a mapped field with the same name as an already mapped field that is inherited from A.
|
|||
|
|
|||
|
Entities support inheritance, polymorphic associations, and polymorphic queries.
|
|||
|
Both abstract and concrete classes can be entities. Entities may extend non-entity
|
|||
|
classes as well as entity classes, and non-entity classes may extend entity classes.
|
|||
|
|
|||
|
> **TIP**
|
|||
|
> The constructor of an entity is only ever invoked when *you* construct a new instance
|
|||
|
> with the *new* keyword. Doctrine never calls entity constructors, thus you are free to use
|
|||
|
> them as you wish and even have it require arguments of any type.
|
|||
|
|
|||
|
+++ Entity states
|
|||
|
|
|||
|
An entity instance can be characterized as being NEW, MANAGED, DETACHED or REMOVED.
|
|||
|
|
|||
|
* A NEW entity instance has no persistent identity, and is not yet associated with an EntityManager and a UnitOfWork (i.e. those just created with the "new" operator).
|
|||
|
* A MANAGED entity instance is an instance with a persistent identity that is associated with an EntityManager and whose persistence is thus managed.
|
|||
|
* A DETACHED entity instance is an instance with a persistent identity that is not (or no longer) associated with an EntityManager and a UnitOfWork.
|
|||
|
* A REMOVED entity instance is an instance with a persistent identity, associated with an EntityManager, that will be removed from the database upon transaction commit.
|
|||
|
|
|||
|
+++ Persistent fields
|
|||
|
|
|||
|
The persistent state of an entity is represented by instance variables. An
|
|||
|
instance variable must be directly accessed only from within the methods of the
|
|||
|
entity by the entity instance itself. Instance variables must not be accessed by
|
|||
|
clients of the entity. The state of the entity is available to clients only through
|
|||
|
the entity’s methods, i.e. accessor methods (getter/setter methods) or other
|
|||
|
business methods.
|
|||
|
|
|||
|
Collection-valued persistent fields and properties must be defined in terms of
|
|||
|
the `Doctrine\Common\Collections\Collection` interface. The collection
|
|||
|
implementation type may be used by the application to initialize fields or
|
|||
|
properties before the entity is made persistent. Once the entity becomes
|
|||
|
managed (or detached), subsequent access must be through the interface type.
|
|||
|
|
|||
|
+++ Serializing entities
|
|||
|
|
|||
|
Serializing entities can be problematic and is not really recommended, at least not as long as an
|
|||
|
entity instance still holds references to proxy objects or is still managed by an EntityManager.
|
|||
|
If you intend to serialize (and unserialize) entity instances that still hold references to proxy objects
|
|||
|
you may run into problems with private properties because of technical limitations.
|
|||
|
Proxy objects implement `__sleep` and it is not possible for `__sleep` to return names of
|
|||
|
private properties in parent classes. On ther other hand it is not a solution for proxy objects
|
|||
|
to implement `Serializable` because Serializable does not work well with any potential cyclic
|
|||
|
object references (at least we did not find a way yet, if you did, please contact us).
|
|||
|
|
|||
|
++ The EntityManager
|
|||
|
|
|||
|
The `EntityManager` class is a central access point to the ORM functionality
|
|||
|
provided by Doctrine 2. The `EntityManager` API is used to manage the persistence
|
|||
|
of your objects and to query for persistent objects.
|
|||
|
|
|||
|
+++ Transactional write-behind
|
|||
|
|
|||
|
An `EntityManager` and the underlying `UnitOfWork` employ a strategy called
|
|||
|
"transactional write-behind" that delays the execution of SQL statements in
|
|||
|
order to execute them in the most efficient way and to execute them at the end
|
|||
|
of a transaction so that all write locks are quickly released. You should see
|
|||
|
Doctrine as a tool to synchronize your in-memory objects with the database in
|
|||
|
well defined units of work. Work with your objects and modify them as usual and
|
|||
|
when you're done call `EntityManager#flush()` to make your changes persistent.
|
|||
|
|
|||
|
+++ The Unit of Work
|
|||
|
|
|||
|
Internally an `EntityManager` uses a `UnitOfWork`, which is a typical
|
|||
|
implementation of the [Unit of Work pattern](http://martinfowler.com/eaaCatalog/unitOfWork.html), to keep track of all the things that need to be done
|
|||
|
the next time `flush` is invoked. You usually do not directly interact with
|
|||
|
a `UnitOfWork` but with the `EntityManager` instead.
|