82 lines
5.2 KiB
Plaintext
82 lines
5.2 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 observing the following restrictions:
|
||
|
||
* An entity class must not be final or contain final methods.
|
||
* All persistent properties/field of any entity class should always be private or protected, otherwise lazy-loading might not work as expected.
|
||
* 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. |