123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224 |
- Frequently Asked Questions
- ==========================
- .. note::
- This FAQ is a work in progress. We will add lots of questions and not answer them right away just to remember
- what is often asked. If you stumble across an unanswered question please write a mail to the mailing-list or
- join the #doctrine channel on Freenode IRC.
- Database Schema
- ---------------
- How do I set the charset and collation for MySQL tables?
- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- You can't set these values inside the annotations, yml or xml mapping files. To make a database
- work with the default charset and collation you should configure MySQL to use it as default charset,
- or create the database with charset and collation details. This way they get inherited to all newly
- created database tables and columns.
- Entity Classes
- --------------
- I access a variable and its null, what is wrong?
- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- If this variable is a public variable then you are violating one of the criteria for entities.
- All properties have to be protected or private for the proxy object pattern to work.
- How can I add default values to a column?
- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- Doctrine does not support to set the default values in columns through the "DEFAULT" keyword in SQL.
- This is not necessary however, you can just use your class properties as default values. These are then used
- upon insert:
- .. code-block:: php
- class User
- {
- const STATUS_DISABLED = 0;
- const STATUS_ENABLED = 1;
- private $algorithm = "sha1";
- private $status = self:STATUS_DISABLED;
- }
- .
- Mapping
- -------
- Why do I get exceptions about unique constraint failures during ``$em->flush()``?
- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- Doctrine does not check if you are re-adding entities with a primary key that already exists
- or adding entities to a collection twice. You have to check for both conditions yourself
- in the code before calling ``$em->flush()`` if you know that unique constraint failures
- can occur.
- In `Symfony2 <http://www.symfony.com>`_ for example there is a Unique Entity Validator
- to achieve this task.
- For collections you can check with ``$collection->contains($entity)`` if an entity is already
- part of this collection. For a FETCH=LAZY collection this will initialize the collection,
- however for FETCH=EXTRA_LAZY this method will use SQL to determine if this entity is already
- part of the collection.
- Associations
- ------------
- What is wrong when I get an InvalidArgumentException "A new entity was found through the relationship.."?
- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- This exception is thrown during ``EntityManager#flush()`` when there exists an object in the identity map
- that contains a reference to an object that Doctrine does not know about. Say for example you grab
- a "User"-entity from the database with a specific id and set a completely new object into one of the associations
- of the User object. If you then call ``EntityManager#flush()`` without letting Doctrine know about
- this new object using ``EntityManager#persist($newObject)`` you will see this exception.
- You can solve this exception by:
- * Calling ``EntityManager#persist($newObject)`` on the new object
- * Using cascade=persist on the association that contains the new object
- How can I filter an association?
- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- Natively you can't filter associations in 2.0 and 2.1. You should use DQL queries to query for the filtered set of entities.
- I call clear() on a One-To-Many collection but the entities are not deleted
- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- This is an expected behavior that has to do with the inverse/owning side handling of Doctrine.
- By definition a One-To-Many association is on the inverse side, that means changes to it
- will not be recognized by Doctrine.
- If you want to perform the equivalent of the clear operation you have to iterate the
- collection and set the owning side many-to-one reference to NULL as well to detach all entities
- from the collection. This will trigger the appropriate UPDATE statements on the database.
- How can I add columns to a many-to-many table?
- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- The many-to-many association is only supporting foreign keys in the table definition
- To work with many-to-many tables containing extra columns you have to use the
- foreign keys as primary keys feature of Doctrine introduced in version 2.1.
- See :doc:`the tutorial on composite primary keys for more information<../tutorials/composite-primary-keys>`.
- How can i paginate fetch-joined collections?
- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- If you are issuing a DQL statement that fetches a collection as well you cannot easily iterate
- over this collection using a LIMIT statement (or vendor equivalent).
- Doctrine does not offer a solution for this out of the box but there are several extensions
- that do:
- * `DoctrineExtensions <http://github.com/beberlei/DoctrineExtensions>`_
- * `Pagerfanta <http://github.com/whiteoctober/pagerfanta>`_
- Why does pagination not work correctly with fetch joins?
- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- Pagination in Doctrine uses a LIMIT clause (or vendor equivalent) to restrict the results.
- However when fetch-joining this is not returning the correct number of results since joining
- with a one-to-many or many-to-many association multiplies the number of rows by the number
- of associated entities.
- See the previous question for a solution to this task.
- Inheritance
- -----------
- Can I use Inheritance with Doctrine 2?
- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
- Yes, you can use Single- or Joined-Table Inheritance in Doctrine 2.
- See the documentation chapter on :doc:`inheritance mapping <inheritance-mapping>` for
- the details.
- Why does Doctrine not create proxy objects for my inheritance hierarchy?
- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- If you set a many-to-one or one-to-one association target-entity to any parent class of
- an inheritance hierarchy Doctrine does not know what PHP class the foreign is actually of.
- To find this out it has to execute a SQL query to look this information up in the database.
- EntityGenerator
- ---------------
- Why does the EntityGenerator not do X?
- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- The EntityGenerator is not a full fledged code-generator that solves all tasks. Code-Generation
- is not a first-class priority in Doctrine 2 anymore (compared to Doctrine 1). The EntityGenerator
- is supposed to kick-start you, but not towards 100%.
- Why does the EntityGenerator not generate inheritance correctly?
- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- Just from the details of the discriminator map the EntityGenerator cannot guess the inheritance hierarchy.
- This is why the generation of inherited entities does not fully work. You have to adjust some additional
- code to get this one working correctly.
- Performance
- -----------
- Why is an extra SQL query executed every time I fetch an entity with a one-to-one relation?
- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- If Doctrine detects that you are fetching an inverse side one-to-one association
- it has to execute an additional query to load this object, because it cannot know
- if there is no such object (setting null) or if it should set a proxy and which id this proxy has.
- To solve this problem currently a query has to be executed to find out this information.
- Doctrine Query Language
- -----------------------
- What is DQL?
- ~~~~~~~~~~~~
- DQL stands for Doctrine Query Language, a query language that very much looks like SQL
- but has some important benefits when using Doctrine:
- - It uses class names and fields instead of tables and columns, separating concerns between backend and your object model.
- - It utilizes the metadata defined to offer a range of shortcuts when writing. For example you do not have to specify the ON clause of joins, since Doctrine already knows about them.
- - It adds some functionality that is related to object management and transforms them into SQL.
- It also has some drawbacks of course:
- - The syntax is slightly different to SQL so you have to learn and remember the differences.
- - To be vendor independent it can only implement a subset of all the existing SQL dialects. Vendor specific functionality and optimizations cannot be used through DQL unless implemented by you explicitly.
- - For some DQL constructs subselects are used which are known to be slow in MySQL.
- Can I sort by a function (for example ORDER BY RAND()) in DQL?
- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- No, it is not supported to sort by function in DQL. If you need this functionality you should either
- use a native-query or come up with another solution. As a side note: Sorting with ORDER BY RAND() is painfully slow
- starting with 1000 rows.
- A Query fails, how can I debug it?
- ----------------------------------
- First, if you are using the QueryBuilder you can use
- ``$queryBuilder->getDQL()`` to get the DQL string of this query. The
- corresponding SQL you can get from the Query instance by calling
- ``$query->getSQL()``.
- .. code-block:: php
- <?php
- $dql = "SELECT u FROM User u";
- $query = $entityManager->createQuery($dql);
- var_dump($query->getSQL());
- $qb = $entityManager->createQueryBuilder();
- $qb->select('u')->from('User', 'u');
- var_dump($qb->getDQL());
|