### [DDC-2953] ArrayHydrator: Not all items hydrated while orderBy Created: 05/Feb/14  Updated: 14/Jul/14

Status: Open
Project: Doctrine 2 - ORM
Component/s: ORM
Affects Version/s: 2.3.4, 2.4.1
Fix Version/s: None
Security Level: All

 Type: Bug Priority: Critical Reporter: Mariusz Jaskółka Assignee: Guilherme Blanco Resolution: Unresolved Votes: 0 Labels: array, hydration Environment: Linux and Windows, PHP5

 Attachments: ArrayHydrator.php     Array_Hydrator_4.2.php     Array_hydrator_4.2_bugfix.php

 Description
 I will explain the problem using example and pseudo-code: I have query like that: SELECT (...) FROM order LEFT JOIN person LEFT JOIN identifier (...) order by (...) The rows returned by query are following (the order is very important): order_id|person_id|identifier_id| 12 |21 |33 | 12 |21 |34 | 11 |21 |35 | 11 |21 |33 | 11 |21 |34 | 12 |21 |35 | After hydration the result is like: result[0][person][identifier][0][id]=33 result[0][person][identifier][0][id]=34 result[1][person][identifier][0][id]=35 result[1][person][identifier][0][id]=34 But it should be: result[0][person][identifier][0][id]=33 result[0][person][identifier][0][id]=34 result[0][person][identifier][0][id]=35 result[1][person][identifier][0][id]=35 result[1][person][identifier][0][id]=34 result[1][person][identifier][0][id]=33 The reason is that ArrayHydrator::_identifierMap contains only object id and parents object id. In may example there is difference in parents parent (grandparent) id.

 Comment by Marco Pivetta [ 05/Feb/14 ] I've started work on this at https://github.com/doctrine/doctrine2/pull/933 Comment by Mariusz Jaskółka [ 06/Feb/14 ] This is how I temporary solved the issue, maybe it can help (attachment). Comment by Marco Pivetta [ 06/Feb/14 ] Mariusz Jaskółka can you provide a diff with current master? This seems to be based off 2.3 or previous versions... Comment by Mariusz Jaskółka [ 06/Feb/14 ] Version 2.4.2 oryginal file and bugfix Comment by Mariusz Jaskółka [ 06/Feb/14 ] Oh sorry it is version 2.4.1 (composer downloaded that version for me). I hope it will be ok. Comment by Marco Pivetta [ 06/Feb/14 ] Mariusz Jaskółka thanks! I'm trying it right now Comment by Mariusz Jaskółka [ 06/Feb/14 ] I added one dimention to $this->_identifierMap to be sure that all object's children's keys will be mapped separately. Comment by Marco Pivetta [ 06/Feb/14 ] Mariusz Jaskółka, I've applied your hotfix at https://github.com/doctrine/doctrine2/commit/c05921032ff6947daca2d7275031e5cde4700634 and the tests seem to pass on my system and on travis. You may want to check it out and see if it works for your use case. Comment by Mariusz Jaskółka [ 06/Feb/14 ] It works for my use case correctly. You apparently forgot to remove/comment line 82 which is not necessary now. Comment by Marco Pivetta [ 06/Feb/14 ] Mariusz Jaskółka fixed, thanks! Comment by Marco Pivetta [ 14/Jul/14 ] I don't think we'll have a fix for this issue for 2.5, as it will probably require a complete rewrite of the array hydrator Comment by Guilherme Blanco [ 14/Jul/14 ] ... and introducing BC breaks. ### [DDC-3062] [GH-997] [FIX] Allow to use ManyToMany with all operators Created: 31/Mar/14 Updated: 08/Jul/14 Status: Open Project: Doctrine 2 - ORM Component/s: None Affects Version/s: None Fix Version/s: 2.5 Security Level: All  Type: Bug Priority: Critical Reporter: Doctrine Bot Assignee: Benjamin Eberlei Resolution: Unresolved Votes: 0 Labels: None  Description  This issue is created automatically through a Github pull request on behalf of bakura10: Message: Hi, ping @guillhermoblanco : I think this may be blocking for 2.5 I introduced not so long ago support for ManyToMany for Criteria. However, I realized my implementation was really incomplete, because I hard-coded the "=" operator (https://github.com/doctrine/doctrine2/pull/885/files#diff-982b7374bbe9d5f4b6b71f4869a446eaR575). This means that it fails in a lot of cases when you use something different than "eq" for Criteria. This PR fixes that, however it's a bit hacky. The SqlExpressionVisitor was made by type hinting for a BasicEntityPersister, preventing us from using us for a collection persister. Therefore I added a new interface to keep BC. There is also a lot of code duplication (the whole "getSelectConditionSQL" was copied from the BasicEntityPersister), but without trait or BC, I have no idea about how to solve it. All tests pass, test were added for other operators. ### [DDC-3212] Remove ArrayHydrator logic Created: 14/Jul/14 Updated: 14/Jul/14 Status: Open Project: Doctrine 2 - ORM Component/s: ORM Affects Version/s: 2.5 Fix Version/s: None Security Level: All  Type: Improvement Priority: Critical Reporter: Marco Pivetta Assignee: Marco Pivetta Resolution: Unresolved Votes: 0 Labels: hydration, hydrator  Description  The Doctrine\ORM\Internal\Hydration\ArrayHydrator ( https://github.com/doctrine/doctrine2/blob/85fbf684363b932a4ebaf543ef059f9ee1e512b0/lib/Doctrine/ORM/Internal/Hydration/ArrayHydrator.php ) is currently very messy and complicated due to the lack of actual Doctrine\ORM\UnitOfWork references when working with it, since we are not dealing with objects. In order to reduce the amount of bugs and code duplication when working with array hydration, I would simply suggest making use of the Doctrine\ORM\Internal\Hydration\ObjectHydrator ( https://github.com/doctrine/doctrine2/blob/85fbf684363b932a4ebaf543ef059f9ee1e512b0/lib/Doctrine/ORM/Internal/Hydration/ObjectHydrator.php ) and its siblings, and then extracting data coming from the results in it as an array. This could be a simple reflection-based extraction (pseudo): class ArrayHydrator { public function hydrateAllData() { foreach ($this->objectHydrator->hydrateAllData() as $object) { yield$this->extractData($object); } } }  The point here is that array-based hydration is not the primary focus of the ORM, and users should probably rely on SQL only when they want array hydration.  Comments  Comment by Marco Pivetta [ 14/Jul/14 ] Note: performance is one of our biggest requirements, and array hydration is meant to achieve that. As I stated above, plain SQL is probably better for this sort of operation, so the issue is more about deprecating the ArrayHydrator completely, providing utilities to manipulate SQL resultsets instead. ### [DDC-3222] PostUpdate event destroying collectionUpdates Created: 21/Jul/14 Updated: 21/Jul/14 Status: Open Project: Doctrine 2 - ORM Component/s: ORM Affects Version/s: 2.4.2 Fix Version/s: None Security Level: All  Type: Bug Priority: Critical Reporter: Jacob Spizziri Assignee: Benjamin Eberlei Resolution: Unresolved Votes: 0 Labels: None Environment: Mac OSX, AMP, php 5.3.27  Description  I have an entity that contains a Many-To-Many Unidirectional association. When the association is updated and the entity is flushed the changes are not being persisted to the database. This is because the postUpdate event is being fired on executeUpdates, which is being called before the collection updates are being processed here:  // Collection updates (deleteRows, updateRows, insertRows) foreach ($this->collectionUpdates as $collectionToUpdate) {$this->getCollectionPersister($collectionToUpdate->getMapping())->update($collectionToUpdate); }  This is occurring in UnitOfWork->commit() lines 333 through 366. Apparently the postUpdate listener I wrote was causing the collectionUpdates property to be erased.

 Comment by Marco Pivetta [ 21/Jul/14 ] What does the listener actually do? Doesn't look like a bug to me... Comment by Jacob Spizziri [ 21/Jul/14 ] I'm using FOSElasticaBundle/ElasticSearch. On the postUpdate event I'm calling fos:elastica:populate on the entity indexes. Heres the code container = $container;$this->logger = $logger; } public function postUpdate(LifecycleEventArgs$args){ $this->index($args); } protected function index($args){$entity = $args->getEntity();$arguments = false; $command = new \FOS\ElasticaBundle\Command\PopulateCommand();$command->setContainer($this->container); //TODO: probably need to specify the --env=prod/dev // update Elastica on Product update if ($entity instanceof Product) { $this->logger->info('Updating Product Search Indexes');$arguments = array( '--index'=>'website', '--type' => 'product' ); } else if ($entity instanceof User) {$this->logger->info('Updating User Search Indexes'); $arguments = array( '--index'=>'website', '--type' => 'user' ); } if($command && $arguments){$input = new ArrayInput($arguments);$output = new NullOutput(); $result =$command->run($input,$output); $this->logger->info('Finished Updating Search Indexes with result: '. strval($result)); } } } ?>  Am I using this event incorrectly? Should I only be using postPersist?

### [DDC-3224] getResult(HYDRATE_OBJECT) with joined query is returning reduced number of rows Created: 23/Jul/14  Updated: 23/Jul/14

Status: Open
Project: Doctrine 2 - ORM
Component/s: ORM
Affects Version/s: 2.4.2
Fix Version/s: None
Security Level: All

 Type: Bug Priority: Critical Reporter: gondo Assignee: Benjamin Eberlei Resolution: Unresolved Votes: 0 Labels: orm Environment: osx, PHP-FPM 5.5.13, nginx/1.6.0, mysql 5.6.19 Homebrew

 Description

given that i have these 2 entities (pseodocode):

/**
* @ORM\Table(name="entity1", options={"collate"="utf8_unicode_ci", "charset"="utf8"})
* @ORM\Entity(repositoryClass="Entity1Repository")
*/
class Entity1 {
/**
* @var integer
* @ORM\Column(name="id", type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
*/
protected $id; /** * @var string * @ORM\Column(name="name", type="string") */ protected$name;

/**
* @var Entity2[]
* @ORM\OneToMany(targetEntity="Entity2", mappedBy="entity1")
*/
protected $entity2; } /** * @ORM\Table(name="entity2", options={"collate"="utf8_unicode_ci", "charset"="utf8"}) * @ORM\Entity() */ class Entity2 { /** * @var integer * @ORM\Column(name="id", type="integer") * @ORM\Id * @ORM\GeneratedValue(strategy="AUTO") */ protected$id;

/**
* @var \DateTime
* @ORM\Column(name="date", type="datetime")
*/
protected $date; /** * @var Entity1 * @ORM\ManyToOne(targetEntity="Entity1", inversedBy="entity2", fetch="EAGER") */ protected$entity1;
}


## tables and data

entity1:

id name
1 Jhon
2 Clare

entity2:

id date entity1_id
1 2011-01-01 00:00:01 1
2 2012-02-02 00:00:02 1
3 2013-03-03 00:00:03 2
4 2014-04-04 00:00:04 2

## my query builder

use Doctrine\ORM\EntityRepository;

class Entity1Repository extends EntityRepository
{
public function getData()
{
$qb =$this
->createQueryBuilder('Entity1')
->select('Entity1, Entity2.date')
->join('Entity1.entity2', 'Entity2', Join::WITH, 'Entity2.date > :date')
->setParameter('date', '2000-01-01 00:00:01')
;
$result1 =$qb->getQuery()->getArrayResult(); // HYDRATE_ARRAY
$result =$qb->getQuery()->getResult(); // HYDRATE_OBJECT

//        return $result1; // return$result2;
}
}


## proper result is this:

id name date
1 Jhon 2011-01-01 00:00:01
1 Jhon 2012-02-02 00:00:02
2 Clare 2013-03-03 00:00:03
2 Clare 2014-04-04 00:00:04

## what is happening

$result1 =$qb->getQuery()->getArrayResult(); // HYDRATE_ARRAY


is really returning proper number of rows

### BUT and here comes the BUG finally:

$result2 =$qb->getQuery()->getResult(); // HYDRATE_OBJECT


is returning just 2 rows:

id name date
1 Jhon 2011-01-01 00:00:01
2 Clare 2013-03-03 00:00:03

this is because somehow entities are made unique.

## my workaround

as a workaround, what i have to do is, to exectute 2 queries. 1st to get just Entity1.ids joined with Entity2.dates by using getArrayResult()
and second query to get Entity1 objeces by unique ids from 1st query.
and than manualy join those results in php.

 Comment by Marco Pivetta [ 23/Jul/14 ] I see that you are using Join::WITH, but not providing a conditional in the example. Are you filtering a fetch-joined association? Comment by gondo [ 23/Jul/14 ] sorry i've tried to simplify my structure as much as it was possible, there are actually real conditions, one of them is date condition (among many others). i've updated my code Comment by Marco Pivetta [ 23/Jul/14 ] There are still some inconsistencies in the issue - where is that query parameter used, for example? Comment by gondo [ 23/Jul/14 ] im using it in EntityRepository (sorry, didnt know thats important) i ll update my code and the whole code is in Symfony2 project (web and command line applications) Comment by Marco Pivetta [ 23/Jul/14 ] What I mean is that in ->setParameter('date', new \DateTime('last month')) , parameter :date does not exist in the DQL. Comment by gondo [ 23/Jul/14 ] i see, sorry its part of JOIN condition, i've updated the code

### [DDC-54] Trigger postLoad events and callbacks after associations have been initialized Created: 15/Oct/09  Updated: 03/Sep/13

Status: In Progress
Project: Doctrine 2 - ORM
Component/s: ORM
Affects Version/s: 2.0-ALPHA2
Fix Version/s: 2.x
Security Level: All

 Type: Improvement Priority: Major Reporter: Roman S. Borschel Assignee: Benjamin Eberlei Resolution: Unresolved Votes: 7 Labels: None

 Description
 Currently the postLoad events and callbacks are triggered after the entity has been created and filled with its "primitive" state but before associations are available. The postLoad events and callbacks should be postponed so that they are triggered after associations have been initialized.

 Comment by Roman S. Borschel [ 30/Aug/10 ] If this is to be included in 2.0 it needs to happen for RC1. However, it is not clear yet whether it will be done in time. Comment by Benjamin Eberlei [ 23/Sep/10 ] How would you solve this Roman? I thought of adding a query hint so that the postLoad inside unit of work is not triggered and gathering all the entities that have a post load event in an array inside the object hydrator, then iterating it after taking the snapshots of all collections inside hydrateAll Comment by Roman S. Borschel [ 24/Sep/10 ] @Benjamin: Not sure what you would use the query hint for but in general that is the approach I had in mind, yes. You can't get around iterating over the entities after the actual hydration. Comment by Benjamin Eberlei [ 27/Sep/10 ] The query hint would do something like:  //TODO: These should be invoked later, after hydration, because associations may not yet be loaded here. if (isset($class->lifecycleCallbacks[Events::postLoad]) && !isset($hints['hydrationPostLoad'])) { $class->invokeLifecycleCallbacks(Events::postLoad,$entity); } if ($this->evm->hasListeners(Events::postLoad) && !isset($hints['hydrationPostLoad'])) { $this->evm->dispatchEvent(Events::postLoad, new LifecycleEventArgs($entity, $this->em)); }  another way would be to move that code out of UoW::createEntity completly and have the persisters call it when they use that method. Comment by Roman S. Borschel [ 28/Sep/10 ] Leaving that code in UoW does not make sense to me, if it is moved, it needs to be moved completely. Why do you think the persisters should do it? Initially I thought collecting the affected entities during hydration and then when hydration is done iterating over them and triggering the postLoad events. Comment by Benjamin Eberlei [ 28/Sep/10 ] Yes but postLoad has to be triggered for non Hydrated entities (i.e. Persister) also Comment by Benjamin Eberlei [ 30/Oct/10 ] Moved back Comment by Kacper Gunia [ 15/Apr/12 ] Hi Gyus, I need access to associations in postLoad or similar event, and my idea is to dispatch new event after full initialisation of object, what do You think about it? If I can help please let me know It's important for me. Comment by Alexander Pasichnick [ 25/Sep/12 ] Now in my PostLoad access to associations is work fine. Why this issue is still in Unresolved status? Comment by Łukasz Cybula [ 11/Oct/12 ] What do you (Roman and Benjamin) think about adding postHydrate event which would be called within ObjectHydrator::hydrateAllData() on every entity collected during hydration? I could prepare a patch for this. I personally think this would be better than adding a hint that changes behaviour of postLoad event. Comment by Slavik Derevyanko [ 07/Jun/13 ] Just stumbled upon this issue. Seems like my associated entities aren't yet loaded in PostLoad event handler. Doctrine version "doctrine/orm": "2.3.1" I've noticed that I have two different paths of execution: 1. When the find() method is used to retrieve the entity, SimpleObjectHydrator is used to perform a hydration and the associations are made available in PostLoad event: bvdpetroleum/vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/ClassMetadataInfo.php.Doctrine\ORM\Mapping\ClassMetadataInfo->invokeLifecycleCallbacks : lineno 2312() bvdpetroleum/vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/ClassMetadataInfo.php at line 2312 bvdpetroleum/vendor/doctrine/orm/lib/Doctrine/ORM/UnitOfWork.php.Doctrine\ORM\UnitOfWork->createEntity : lineno 2610() bvdpetroleum/vendor/doctrine/orm/lib/Doctrine/ORM/UnitOfWork.php at line 2610 bvdpetroleum/vendor/doctrine/orm/lib/Doctrine/ORM/Internal/Hydration/SimpleObjectHydrator.php.Doctrine\ORM\Internal\Hydration\SimpleObjectHydrator->hydrateRowData : lineno 135() bvdpetroleum/vendor/doctrine/orm/lib/Doctrine/ORM/Internal/Hydration/SimpleObjectHydrator.php at line 135 bvdpetroleum/vendor/doctrine/orm/lib/Doctrine/ORM/Internal/Hydration/SimpleObjectHydrator.php.Doctrine\ORM\Internal\Hydration\SimpleObjectHydrator->hydrateAllData : lineno 50() bvdpetroleum/vendor/doctrine/orm/lib/Doctrine/ORM/Internal/Hydration/SimpleObjectHydrator.php at line 50 bvdpetroleum/vendor/doctrine/orm/lib/Doctrine/ORM/Internal/Hydration/AbstractHydrator.php.Doctrine\ORM\Internal\Hydration\AbstractHydrator->hydrateAll : lineno 111() bvdpetroleum/vendor/doctrine/orm/lib/Doctrine/ORM/Internal/Hydration/AbstractHydrator.php at line 111 bvdpetroleum/vendor/doctrine/orm/lib/Doctrine/ORM/Persisters/BasicEntityPersister.php.Doctrine\ORM\Persisters\BasicEntityPersister->load : lineno 678() bvdpetroleum/vendor/doctrine/orm/lib/Doctrine/ORM/Persisters/BasicEntityPersister.php at line 678 bvdpetroleum/vendor/doctrine/orm/lib/Doctrine/ORM/EntityManager.php.Doctrine\ORM\EntityManager->find : lineno 413() bvdpetroleum/vendor/doctrine/orm/lib/Doctrine/ORM/EntityManager.php at line 413 bvdpetroleum/vendor/doctrine/orm/lib/Doctrine/ORM/EntityRepository.php.Doctrine\ORM\EntityRepository->find : lineno 131() bvdpetroleum/vendor/doctrine/orm/lib/Doctrine/ORM/EntityRepository.php at line 131 2. When the DQL is used, ObjectHydrator is used to perform a hydration, and the associations aren't made ready in PostLoad event: bvdpetroleum/src/BVD/PetroleumBundle/Entity/FuelCard.php.BVD\PetroleumBundle\Entity\FuelCard->retrieveNumbers : lineno 304() bvdpetroleum/src/BVD/PetroleumBundle/Entity/FuelCard.php at line 304 bvdpetroleum/vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/ClassMetadataInfo.php.Doctrine\ORM\Mapping\ClassMetadataInfo->invokeLifecycleCallbacks : lineno 2312() bvdpetroleum/vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/ClassMetadataInfo.php at line 2312 bvdpetroleum/vendor/doctrine/orm/lib/Doctrine/ORM/UnitOfWork.php.Doctrine\ORM\UnitOfWork->createEntity : lineno 2610() bvdpetroleum/vendor/doctrine/orm/lib/Doctrine/ORM/UnitOfWork.php at line 2610 bvdpetroleum/vendor/doctrine/orm/lib/Doctrine/ORM/Internal/Hydration/ObjectHydrator.php.Doctrine\ORM\Internal\Hydration\ObjectHydrator->_getEntity : lineno 245() bvdpetroleum/vendor/doctrine/orm/lib/Doctrine/ORM/Internal/Hydration/ObjectHydrator.php at line 245 bvdpetroleum/vendor/doctrine/orm/lib/Doctrine/ORM/Internal/Hydration/ObjectHydrator.php.Doctrine\ORM\Internal\Hydration\ObjectHydrator->hydrateRowData : lineno 478() bvdpetroleum/vendor/doctrine/orm/lib/Doctrine/ORM/Internal/Hydration/ObjectHydrator.php at line 478 bvdpetroleum/vendor/doctrine/orm/lib/Doctrine/ORM/Internal/Hydration/ObjectHydrator.php.Doctrine\ORM\Internal\Hydration\ObjectHydrator->hydrateAllData : lineno 149() bvdpetroleum/vendor/doctrine/orm/lib/Doctrine/ORM/Internal/Hydration/ObjectHydrator.php at line 149 bvdpetroleum/vendor/doctrine/orm/lib/Doctrine/ORM/Internal/Hydration/AbstractHydrator.php.Doctrine\ORM\Internal\Hydration\AbstractHydrator->hydrateAll : lineno 111() bvdpetroleum/vendor/doctrine/orm/lib/Doctrine/ORM/Internal/Hydration/AbstractHydrator.php at line 111 bvdpetroleum/vendor/doctrine/orm/lib/Doctrine/ORM/AbstractQuery.php.Doctrine\ORM\AbstractQuery->execute : lineno 747() bvdpetroleum/vendor/doctrine/orm/lib/Doctrine/ORM/AbstractQuery.php at line 747 Hope this helps to solve the issue. Comment by Valera Leontyev [ 03/Sep/13 ] This issue is very important in my opinion. I can't come up with any workaround to resolve it. Only possible way to detect fully loaded state is to call entity method from outside which is too rude and dirty. ### [DDC-128] Consider adding EntityManager#link/unlink methods for direct association manipulation Created: 07/Nov/09 Updated: 29/Dec/10 Status: Open Project: Doctrine 2 - ORM Component/s: ORM Affects Version/s: 2.0-ALPHA2 Fix Version/s: 2.x Security Level: All  Type: New Feature Priority: Major Reporter: Roman S. Borschel Assignee: Roman S. Borschel Resolution: Unresolved Votes: 1 Labels: None Issue Links:  Reference is referenced by DDC-546 New fetch mode EXTRA_LAZY for collect... Resolved  Description  A problem when working with collection-valued associations is that almost all operations except add($obj) require the collection to become initialized in order for the operation to be performed properly. While this is all correct and beautiful OO-wise it may be problematic at times with regards to performance. Hence we might want to consider to provide some convenient methods along the lines of link/unlink (name suggestions?) which allow more direct, less OO collection manipulation. Such methods obviously would bypass the normal object lifecycle and the changes done through these methods will not be reflected in the in-memory objects and collections, unless the user keeps them in-synch himself.

 Comment by Benjamin Eberlei [ 11/Dec/09 ] Questions I suppose link and unlinked entities would then handled by UnitOfwork commit also? Since the collection is not initialized, one does not know upfront if the action will be successful, what happens if: an entity is linked with a collection, although they are already connected. an entity is unlinked from a collection it is not in. Regarding the naming, i like link/unlink. Comment by Roman S. Borschel [ 17/Dec/09 ] What do you mean by "handled by UnitOfWork commit" ? Whether the SQL is "scheduled" or executed immediately? Interesting question. Scheduling would probably be better but also more difficult. As far as usage is concerned, I currently imagine it as follows: // EntityManager#link($sourceObj,$field, $targetObj)$user = $em->getReference($userId); // $userId probably from request parameters$address = $em->getReference($addressId); // $addressId probably from request parameters$em->link($user, 'addresses',$address);  "What happens if: an entity is linked with a collection, although they are already connected." Probably an SQL error which results in an exception from the driver. Depends on the database constraints though. "What happens if: an entity is unlinked from a collection it is not in" Probably nothing, at least not from the SQL side. An exception could be thrown from Doctrine itself if the update affected 0 rows. Thanks for these initial questions. Thats definitely food for thought. Keep it coming. Comment by Roman S. Borschel [ 26/Aug/10 ] Pushed back.

### [DDC-138] Allow for mixed inheritance mapping Created: 12/Nov/09  Updated: 24/Dec/10

Status: Open
Project: Doctrine 2 - ORM
Component/s: DQL, Mapping Drivers, ORM
Affects Version/s: None
Fix Version/s: None
Security Level: All

 Type: New Feature Priority: Major Reporter: Reinier Kip Assignee: Roman S. Borschel Resolution: Unresolved Votes: 3 Labels: None

 Duplicate is duplicated by DDC-265 Possibility for Nested Inheritance Open

 Description
 Requesting implementation of mixed inheritance mapping (class table inheritance and single table inheritance). This would be especially handy when the difference between certain classes is only "implementational" (i.e. a subclass only functions differently/implements abstract methods and does not specify any additional fields). Using class table inheritance would result in tables only containing an id column.

### [DDC-213] Persist order of collections Created: 15/Dec/09  Updated: 27/Jun/14

Status: Open
Project: Doctrine 2 - ORM
Component/s: None
Affects Version/s: 2.0
Fix Version/s: 3.0
Security Level: All

 Type: New Feature Priority: Major Reporter: Roman S. Borschel Assignee: Roman S. Borschel Resolution: Unresolved Votes: 15 Labels: None

 Duplicate is duplicated by DDC-181 Order of many-to-many relationship Resolved Reference is referenced by DDC-250 ArrayCollection Key Column @indexBy Resolved

 Description
 A Collection is like a php array, an ordered map. Hence there should be the possibility to persist this order.

 Comment by Christian Heinrich [ 21/May/10 ] Roman, I'd like to do this one as I have currently a use case for this. Do you have any idea of how to do this? What I'm wondering is whether it is possible to implement this without user intervention. (This would simply mean "store the entities as they were added"). But this would need another column in DB that we'd have to add within oneToMany / manyToMany relationships, but in this case one could save a serialized array holding "entityId => position" key / value pairs. Afterwards, one could easily rebuild / reorder the collection via $collection->set($entity, $order[$entity->identifier]); If you've got another thought about this, please don't hesitate to point me into the right direction! Comment by Benjamin Eberlei [ 22/May/10 ] this won't be implemented until 2.1, since its a pretty complex feature. Changes are probably required in: 1. CollectionPersister - Add a new collection persister that takes the position into account 2. SchemaTool - Add a 'col_position' column to either the many-to-many or the one-to-many tables. 3. EntityPersister - Use and extend current order-by support to make the sorting happen You can implement this already though with some performance hit in update scenarios. If you use the ORDER BY support and implement an API around your entity that abstracts those changes and always sets a "position" field on the many entity that is supposed to be sorted. Comment by Roman S. Borschel [ 22/May/10 ] I don't think we necessarily need a new collection persister. Simply adjusting the ManyToManyPersister to be able to deal with it might be sufficient. For OneToMany, that is always persisted from the "many" side, thus there is no collection persister, we would need to adjust the normal persisters. They key element for the user should be a new annotation (or corresponding xml/yaml element) @OrderColumn. By default the order should not be persistent, only when an @OrderColumn annotation is present. The name of the order column can have a default, i.e. "position". Thus this enhancement of persisting the order should be fully backwards compatible. Comment by Roman S. Borschel [ 22/May/10 ] On another note, the getInsertDiff/getDeleteDiff methods of PersistentCollection should already be "ready" for this. That is, when an element in the collection changed only its position, this is already tracked as a change. However the ManyToManyPersister issues no "UPDATE" queries, it simply deletes and inserts. A position change may be more effectively persisted with an UPDATE. Comment by Benjamin Eberlei [ 30/Sep/10 ] From a mailinglist entry, required check/changepoints: 1. ClassMetadata of Many-To-Many associations have to be extended to publish the required datastructure to the ORM. 2. All Metadata Mapping Drivers have to be extended 3. Persisters\ManyToManyCollectionPersister has to be extended to save the key in the many to many table if desired by the user. 4. Schema-Tool has to be extended to create the additional column. 5. PersistentCollection has to be extended so that lazy loading of collections with additional key works. 6. Array- and ObjectHydrator have to be extended to allow fetch join of collections with key column. 7. Discuss wheather to support this for One-To-Many also with the key-column on the many side. This is much more tricky internally though. Comment by Benjamin Eberlei [ 24/Dec/10 ] Push back to 2.x, we will have support for DDC-250 first and for this at a later release. Comment by Thomas Tourlourat - Armetiz [ 07/Feb/12 ] Hi there, I'm looking for this feature. Benjamin Eberlei said that : "You can implement this already", but I don't understand the "how to". Also, The problem should be solve if RDBMS had a "natural" order. An order based on item position inside table. To get this feature without any change on Doctrine, I have remplace the PK defined by the target & mapped field identifier. The new PK is a new field with type "integer" and with auto-increment enable. In this configuration, Doctrine use the "natural" order of the RDBMS. And I can change order of my item inside Collection and persist it. It's an very bad solution, but It work before an official support. Waiting for advices, and solutions, Thomas. Comment by Thomas Tourlourat - Armetiz [ 08/Feb/12 ] Answering to Benjamin Eberlei on the "7. Discuss wheather to support this for One-To-Many also with the key-column on the many side. This is much more tricky internally though.". I think that for One-To-Many relations, if user want to store the collection order, Doctrine can store the One-To-Many as Many-To-Many with a "model" limitation. In that case, if storing order collection for Many-To-Many work, it should work for One-To-Many. What do you think about it ? Comment by Nicolas [ 29/Feb/12 ] I think that it must be possible to have two keys ordering : the order isn't obligatory reversible. For exemple with user and group : You can order groups for one user : with preference by exemple, or importance. And with a different order, users for a group : rank by example. And maybe more, if you decide to add multi-order : an user show group by his rank in it, if his rank is identical, the order is make by love preference, and after by the importance given by the user (not necessary a number, if we imagine filter on them). So a default order can be choice with parametized fields and could be :  @ManyToMany(targetEntity="Group") ... @JoinFields ( rank: { type: int} , preference:{type:int}, importance:{type: string, length: 40} ) @OrderByJoinFields({"rank" = "ASC", "preference"="ASC", "importance"="ASC" } )  In this case the order must be optional and would be clean if another order appears in the same scope (DQL...). And manytomany became virtual entities act as other entities except they don't appears permetting in the same time a better conception. So if the solution take in DDC-181 will become the only solution. This would a good idea to document this. Because, this seems to me a very important point. My last point is even an unique ordering field created in the join table will be a big and usefull improvement. Thank a lot for your beautiful work. Comment by Thomas Tourlourat - Armetiz [ 29/Feb/12 ] In my point of view, a collection can be order in a single way only. If you want to add more than one order between User & Group, it's a new collection, a new relation. Like : User.memberOf() : Group[] Group.members() : User[] Group.importantMembers() : User[] And it's your role to keep a consistency between members & importantMembers array. Because ManyToMany join table is the reflection of a state of an ArrayCollection. It's not a usefull feature to be able to store all of the state of an ArrayCollection, even the order of this Array. It's just a normal feature that is really missing Thomas. Comment by Nicolas [ 29/Feb/12 ] I don't think: If you have three collection, you duplicate one relation 3 times and it's easy in consequence to lost the data integrity and unicity. By example : Thomas have rank 10 in Admin Thomas think the admin group has importance noted 3 on all of his groups. If a responsable of admin group decide to delete Thomas from it. Thomas, in his ordered list of groups, think always to be in group admin. So in my idea, the many to many relation isn't just an array collection, but should be an virtual entity. In UML or in Merise method this is a common problem to have a parametized relation. I think an orm should just implement this. Comment by Thomas Tourlourat - Armetiz [ 29/Feb/12 ] Hum, I agree with you.. In a SQL Schema, it's a good choice to add many fields in a ManyToMany join table to description "order". Comment by Thomas Tourlourat - Armetiz [ 07/Mar/12 ] I just want to add a piece of Doctrine ORM Document : "When working with collections, keep in mind that a Collection is essentially an ordered map (just like a PHP array). That is why the remove operation accepts an index/key. removeElement is a separate method that has O ( n) complexity using array_search, where n is the size of the map." Comment by Thomas Tourlourat - Armetiz [ 23/Mar/12 ] Hi there, After several discussions. on IRC, I have changed my point of view. Doctrine Documentation says : "When working with collections, keep in mind that a Collection is essentially an ordered map (just like a PHP array)". So, I think that Doctrine have to be able to store or not the order of a Collection. By adding a new field on the Joined table to store the position of each elements. But I not agree with @Nicolas. Because in his case, he's talking about Association Class : http://etutorials.org/Programming/UML/Chapter+6.+Class+Diagrams+Advanced+Concepts/Association+Class/ Because he's talking of a business logic, he's talking of a dedicated Entity class. What do you think about it ? Thomas; Comment by Thomas Tourlourat - Armetiz [ 31/Aug/12 ] Any news ? Comment by Matthieu Napoli [ 16/Oct/12 ] Hi, any news on this? If I may add any info to this feature request, maybe something like JPA/Hibernate could be a good start? The idea in Hibernate is that you persist the order of the list in an extra column. This column is not a field of the entity however. Comment by Albert Casademont [ 27/Jun/14 ] +1, this would be indeed a very nice thing. We are using the @OrderBy annotation as a workaround but it's not quite the same thing Comment by Marco Pivetta [ 27/Jun/14 ] Moved to 3.x

### [DDC-265] Possibility for Nested Inheritance Created: 21/Jan/10  Updated: 16/Jan/13

Status: Open
Project: Doctrine 2 - ORM
Component/s: ORM
Affects Version/s: None
Fix Version/s: None
Security Level: All

 Type: New Feature Priority: Major Reporter: Michael Fürmann Assignee: Roman S. Borschel Resolution: Unresolved Votes: 0 Labels: None

 Duplicate duplicates DDC-138 Allow for mixed inheritance mapping Open

 Description
 It would be great if Doctrine had the possibility to define a further inharitance in a subclass. Example: There is a class DataObject managing things like created- and lastedit- timestamps, archiving objects before updates, ... One of the sub-objects is Content. There are several types of content. Written directly to a database field, read from a textfile on server, executed php file on server, loaded from another server via xmlrpc and so on. I'd like to use a single table inheritance to map all information of the different content objects in one table. If I understand the model right the only alternate solution would be to write each single content object to the discriminator map of DataObject.

 Comment by Benjamin Eberlei [ 21/Jan/10 ] The DataObject you describe is a no-go for Doctrine 2. Its just a very bad practice. Inheritance Mapping is for REAL inheritance only, otherwise you shouldnt go with a relational database in the first place. You should use the Event system for such changes, it offers you roughly the same possibilities and keeps you from having to use inheritance mapping. You could still create an abstract data object and define the fields that will be used in each "implementation" and then in events do something like: if ($entity instanceof DataObject) {$entity->updated(); $archiver->makeSnapshot($entity); }  Comment by Jonathan H. Wage [ 20/Mar/10 ] With this patch I think you could setup a nice similar model where you can introduce new children of this parent class and have it added to the discriminator map from the child instead of having to modify the parents mapping information. http://www.doctrine-project.org/jira/browse/DDC-447

### [DDC-274] Class and namespace naming inconsistency Created: 24/Jan/10  Updated: 26/Jun/14

Status: In Progress
Project: Doctrine 2 - ORM
Component/s: None
Affects Version/s: None
Fix Version/s: 3.0
Security Level: All

 Type: Improvement Priority: Major Reporter: Glen Ainscow Assignee: Guilherme Blanco Resolution: Unresolved Votes: 1 Labels: None

 Description
 There are inconsistencies with some class and namespace names that include acronyms. Examples: Classes with upper-casing: ORMException, DBALException, OCI8Connection, etc. Classes with proper-casing: RunDqlTask, CliException, MySqlPlatform, etc. Namespaces with upper-casing: DBAL, ORM, Doctrine\DBAL\Driver\PDOMsSql, etc. Namespaces with proper-casing: Doctrine\Common\Cli, Doctrine\DBAL\Tools\Cli\, Doctrine\ORM\Id, etc. There is more proper-casing than upper-casing. IMHO, proper-casing is better as it's easier to read "SqlException" than it is to read "SQLException" (the "E" looks like part of the acronym), and things like "CLITask" can be avoided. I discussed this a bit with Benjamin and Guilherme, and they were unsure and said that the whole team needed to reach consensus. I'm leaving the priority as "Major" because this should probably be fixed sooner rather than later to prevent compatibility breaks.

### [DDC-298] Allow Entity to hold a collection of a single primitive type Created: 02/Feb/10  Updated: 20/Dec/13

Status: Open
Project: Doctrine 2 - ORM
Component/s: ORM
Affects Version/s: 2.1
Fix Version/s: 2.x
Security Level: All

 Type: New Feature Priority: Major Reporter: Benjamin Eberlei Assignee: Benjamin Eberlei Resolution: Unresolved Votes: 5 Labels: None

 Duplicate is duplicated by DDC-2806 @ElementCollection does work as expected Resolved

 Description
 Sometimes you want to save arbitrary information for an entity using a key -> value array-structure. JPA supports this by means of the @ElementCollection annotation with allows to specify HashMaps for example. I propose a new AssocationMapping called "ElementMapping" / "ElementCollection" and annotations (options): ElementCollection + elementTable + keyType + keyLength + keyColumnDefinition + valueType + valueLength + valueColumnDefinition  The key and value definitions are necessary for converting and schema generation. The implementation would make use of the PersistentCollection at all times and work as any other persistent collection just with primitive types. Restrictions for a first implementation: Only available as a Lazy-Load Collection, no hydration with the source entity Can't be used in queries alike "entity.colname.key = ?1" Use-Case: $entity->options['foo'] = 'bar';$entity->options['bar'] = 'baz';  This could be done for 2.0 imho, adding the necessary changes and optimizations could then be scheduled for 2.1

 Comment by Benjamin Eberlei [ 02/Feb/10 ] In this implementation Schema-Tool would generate a table: elementTable (entity_id-1, ..., entity_id-n, key, value) and using the Platform Type Generation of keyType and valueType Comment by Benjamin Eberlei [ 02/Feb/10 ] Column Names should be Change-able also since there could be people who name their primary keys "key" and "value" o_O Comment by Benjamin Eberlei [ 02/Feb/10 ] Ordering could be implemented on top of this using the @OrderColumn JPA implementation by adding another column to the table with a numeric order that will be "order by"'d on select time. Comment by Benjamin Eberlei [ 24/Dec/10 ] Pushed back Comment by Richard Michael Coo [ 10/Oct/13 ] Any news on this? It has been almost 3 years since its last update =)

### [DDC-349] Add support for specifying precedence in joins in DQL Created: 18/Feb/10  Updated: 01/May/13

Status: Open
Project: Doctrine 2 - ORM
Component/s: DQL
Affects Version/s: 2.0-ALPHA4
Fix Version/s: None
Security Level: All

 Type: Improvement Priority: Major Reporter: Dennis Verspuij Assignee: Roman S. Borschel Resolution: Unresolved Votes: 1 Labels: None

Attachments: DDC349Test.patch
 Duplicate is duplicated by DDC-1256 Generated SQL error with DQL WITH and... Resolved

 Description
 This request is in followup to my doctrine-user message "Doctrine 2.0: Nested joins'. I am a bit surprised by the responses in that defining precedences in joins by placing parenthesis around join expressions is not well-known. Although not in the original SQL92 specification it is a major and important feature offered by all the RDBMS's that Doctrine 2 supports, and oftenly performs better than using subselects or alike. Doctrine 1 did not support it, but imho Doctrine 2 should support it to be a mature allround ORM. As a short example the following is a SQL statement with a nested join, where the nesting is absolutely necessary to return only a's together with either both b's and c's or no b's and c's at all: SELECT * FROM a A LEFT JOIN ( b B INNER JOIN c C ON C.b_id = B.id ) ON B.a_id = A.id In order for Doctrine 2 to support this the BNF should be something like: Join ::= ["LEFT" ["OUTER"] | "INNER"] "JOIN" ( "(" JoinAssociationPathExpression ["AS"] AliasIdentificationVariable Join ")" | JoinAssociationPathExpression ["AS"] AliasIdentificationVariable ) [("ON" | "WITH") ConditionalExpression] instead of the current: Join ::= ["LEFT" ["OUTER"] | "INNER"] "JOIN" JoinAssociationPathExpression ["AS"] AliasIdentificationVariable [("ON" | "WITH") ConditionalExpression] This would allow DQL like: SELECT A, B, C FROM a A LEFT JOIN ( A.b B INNER JOIN B.c C ) WITH B.something = 'value' AND C.something = 'othervalue' What further needs to be done is that the DQL parser loosly couples the ConditionalExpression to any of the previously parsed JoinAssociationPathExpression's instead of tieing it explicitely to the JoinAssociationPathExpression that preceedes it according to the old BNF notation. The new BNF should however not require any changes to the hydrator. Therefore I have the feeling that improving the DQL parser for nested joins does not require extensive work, while the benefit of running these kind of queries is considerable. As an extra substantiation here are links to (BNF) FROM clause documentations of the RDBMS's that Doctrine 2 supports, they all show support for nested joins: MySQL: http://dev.mysql.com/doc/refman/5.0/en/join.html PostgreSQL: http://www.postgresql.org/docs/8.4/interactive/sql-select.html#SQL-FROM and http://www.postgresql.org/docs/8.1/interactive/explicit-joins.html MSSQL: http://msdn.microsoft.com/en-us/library/ms177634.aspx Oracle: http://download.oracle.com/docs/cd/E11882_01/server.112/e10592/statements_10002.htm#CHDDCHGF SQLite: http://www.sqlite.org/syntaxdiagrams.html#single-source I surely hope you will consider implementing this improvement because it would save me and others from the hassle of writing raw SQL queries or executing multiple (thus slow) queries in DQL for doing the same. Thanks anyway for the great product so far!

 Comment by Guilherme Blanco [ 13/Apr/10 ] This seems to be a valid issue to me. This implementation is the actual solution to associations retrieval that are inherited (type joined). Example: /** Joined */ class Base {} class Foo extends Base {} class Bar { public $foo; } // This causes the CTI to link as INNER JOIN, which makes the result become 0 // il if you have no Foo's defined (although it should ignore this)$q = $this->_em->createQuery('SELECT b, f FROM Bar b LEFT JOIN b.foo f');  Comment by Roman S. Borschel [ 13/Apr/10 ] Yes, this is a possible solution for DDC-512 but on the SQL level. I still don't see this as appropriate for DQL, it just doesnt make sense to me, DQL joins object associations, there is no precedence. Comment by Roman S. Borschel [ 13/Apr/10 ] So, no, this has nothing to do with DDC-512. DDC-512 can even be fixed differently as outlined in my comments there. Comment by Roman S. Borschel [ 13/Apr/10 ] On a side note I would still like to know/see the following for this issue: Some realisitic DQL examples where this feature would be essential, i.e. there is no other way to do it. This also means explaining what the impact on the resulting object graph is and why it makes sense. Which other ORMs support this on the OQL/Criteria level? So far, my stance on this issue is: 1) It doesnt make sense (semantically) in DQL 2) Its rarely needed 3) When you really need it you can use a NativeQuery anyway and use this nesting in SQL, where it probably belongs and makes more sense 4) It would (unnecessarily) complicate DQL Thus I am currently leaning towards "Wont fix" for this issue. Comment by Dennis Verspuij [ 13/Apr/10 ] Hi Roman. I understand your doubts, and I have been breaking my head over creating a realistic example the last few hours that would hopefully convince you for implementing this feature. But actually I cannot find one that you wouldn't consider to be trivial. I do have a number of very complex optimized queries written for sportskickoff dot com (using Doctrine 1.2) but they are probably hard to understand because they may not be selfdescribing. Below is one example literally ripped from the application. Still they often can be broken down to my example query in this ticket's description, but applied grouping, additional other joins on the root component and/or other criteria made them impossible to rewrite using subselects or choosing another root component. Most often they just performed way best using the nested syntax and saved me a number of additional queries. SELECT A.id, A.username, A.balance, COALESCE(SUM(B.stake), 0) AS sumstake, COUNT(B.id) AS nrbets FROM account A LEFT JOIN ( bet B INNER JOIN game G ON G.id = :GAMEID AND B.timestampcompletion BETWEEN G.timestampstart AND G.timestampend ) ON B.accountid = A.id AND B.timestampcompletion IS NOT NULL WHERE A.Status & :ACTIVEORDISQUALIFIED = :ACTIVE GROUP BY A.id, A.username, A.balance ORDER BY A.balance DESC, sumstake ASC, nrbets ASC, A.username ASC But let's put it another way. I would also like this feature to be supported in DQL because I just do not want to use native queries. Why would I want to use native queries if it can be done using DQL? In DQL I work with class names and field names, and they may differ from the underlying table and column names. Doctrine takes care of that mapping based on my schema/annotations and I do not have to "know" these mappings. In native queries I suddenly do have to "know" these mappings. I use Doctrine because it makes my application portable and enables me to work with my database in an OOP way like I do in my model, abstracting things. The need for native queries partly reverts the benefits Doctrine offers in the first place. Btw, I recall to have successfully used the nested join syntax in HQL (.NET Hibernate) but I cannot find examples on the web or a BNF notation. Furthermore, in reply to your stances: 1) It indeed doesnt make sense (semantically) in DQL, it only makes the result set different, but not the way data is hydrated into objects; 2) Its indeed rarely needed for inserting, updating and populating basic lists but it allows you to better select what combinations of associated rows are joined and which not in more optimized queries without having to use native queries, or because they perform better than using subseletcs and alike. 3) Not having to use native queries is just an extra reason for using Doctrine and maintains the abstraction the ORM provides througout on'es whole application 4) Why would it complicate DQL, if people do not know about or understand the feature it wouldn't matter because not using parenthesises is the default way to specify joins? Well, this is it, can't find any more words to promote and make you enthusiastic.... lol. Comment by Dennis Verspuij [ 13/Apr/10 ] Ok, I have not given up yet... , here's a "stupid" example. Imagine a book store that sells books of various authors and keeps track of those sales. Let's say you would have an admin page that lists all authors, and for each author its also shows the books and their sales dates since january 1st, but only for those books that were actually sold and contain an A in its name. An optimized SQL query to fetch all the information at once would be something like: SELECT A., B., S.* FROM author A LEFT JOIN ( book B INNER JOIN sale S ON S.book_id = B.id AND S.dt >= '2010-01-01' ) ON B.author_id = A.id AND A.name LIKE '%A%' In DQL it would then be something like: SELECT A., B., S.* FROM author A LEFT JOIN ( book B INNER JOIN sale S WITH S.dt >= '2010-01-01' ) WITH A.name LIKE '%A%' If the database would contain thousands of books, but sales for just a few books, this will definitely perform better than using subselects. Off course one would like to fetch array graphs instead of objects for further optimization, but this hopefully shows my point. I have attached a test casefor a similar query, though without the additional join constraints for clarity. I surely hope you can consider it. One last note, you shouldn't be afraid that nesting joins is not in the ansi SQL spec. Select queries are about record sets and products between these sets, tables are just the basic means of providing record sets to the query. This is an important terminological difference to think about. Specifying precedence with parenthesis around joins is a logical and natural evolution of the ansi sql standard. For example views are a good proof of this concept, I could define book B INNER JOIN sale S as a view and LEFT JOIN that to authors to get effectively the same result set as the above example. The database server would internally perform the same query (though may additionally take indexes on the view into account). That said, rdbm's that support this syntax would certainly never drop the feature, as its not a feature but just plain logical and smart querying! P.S. I had a hard time finding out how to run the test cases, I could not find it in the Doctrine 2 documentation, development wiki, cookbook or any other place, while finally it was as easy as running phpunit Doctrine_Tests_AllTests from within the tests/ directory, or just phpunit Doctrine_Tests_ORM_Functional_Ticket_DDC349Test for my test. Could you please add some info about this somewhere, it might save others some googling. Comment by Dennis Verspuij [ 13/Apr/10 ] Test case as SVN patch using a parenthesized join. Just remove the parenthesises from the query to have it fail... Comment by Roman S. Borschel [ 29/May/10 ] @"The need for native queries partly reverts the benefits Doctrine offers in the first place." That is something I hugely disagree with. Neither SQL abstraction, nor database vendor independence is the main purpose of an ORM like Doctrine 2. It is the state management of your objects, the transparent change tracking, lazy-loading and synchronization of the object state with the database state and nothing of this gets lost when using native queries. We could rip out DQL and any other querying mechanism except a basic find() (and lazy-loading, of course), only providing the native query facility and even only supporting MySQL and would still retain all the core ORM functionality. NativeQuery is one of the best and core "features" of the project. It is even the foundation for DQL. A DQL query is nothing more than an additional (beautiful) abstraction but what comes out is a native query + a ResultSetMapping, the same thing you can build yourself in the first place, even using the mapping metadata to construct the query. Nothing forces you to hardcode table and column names in native queries if you don't want that. Just use the mapping metadata, DQL does the same. SQL abstraction and database vendor independence is icing on the cake, not the heart of the ORM. ### [DDC-536] Remove the _ prefix from private and protected members Created: 23/Apr/10 Updated: 16/Apr/14 Status: Open Project: Doctrine 2 - ORM Component/s: None Affects Version/s: None Fix Version/s: 3.0 Security Level: All  Type: Improvement Priority: Major Reporter: Roman S. Borschel Assignee: Guilherme Blanco Resolution: Unresolved Votes: 1 Labels: None  Description  The reasoning is simple: The prefix "_" is usually either used for easier distinction of instance variables from other, i.e. local variables, instead of always using "this." (often seen in C#), or it is used to signal that a member is not meant to be accessed from outside of the class when the language does not have visibility modifiers (PHP4). Since you always have to use "$this->" in PHP5+ when accessing instance members and there are visibility modifiers, the "_" is largely superfluous and just makes the verbose OO code even more verbose. Maybe the following find/replace steps will do the job almost completely: "private $_" => "private$" "protected $_" => "protected$" "$this->_" => "$this->" 

 Comment by Benjamin Eberlei [ 27/Apr/10 ] i just found a possible BC issue with this. EntityRepository is allowed to be extended by us, it has several variables that are underscore prefixed. How to proceed in this case? Comment by Roman S. Borschel [ 27/Apr/10 ] I know but its not really a problem I think. We should just decide whether we make them private in the first place and provide getters instead (which would have avoided this problem in the first place). Comment by Roman S. Borschel [ 27/Apr/10 ] Leaving the prefixes on the repository class only is also an option... but I dont think thats necessary. Comment by Benjamin Eberlei [ 27/Apr/10 ] can we commit getters for Beta 1 then? We could give everyone a period until Beta 2 to fix their code and then make the change. EntityRepository is the only class that is meant to be userland extendable to my knowledge, so this should be the only problem to adress Comment by Roman S. Borschel [ 27/Apr/10 ] Yes, you can add getters and commit right away if you want. Plus adding a note on the upgrade document that direct access of these properties is deprecated. Comment by Roman S. Borschel [ 27/Apr/10 ] Persisters will be also extensible some day in userland but they need more polish for that, I've already started with it Comment by Johnny Peck [ 19/Nov/10 ] Is this still planned? Searching the code base finds this is not being implemented. It would be a good idea to implement the change sooner than later if it will be done at all. Also, +1 for the change. It makes complete sense. Comment by Guilherme Blanco [ 16/Apr/14 ] Moving to 3.0 as this can potentially create BC breaks

### [DDC-585] Create a coding standards document Created: 13/May/10  Updated: 17/Apr/14

Status: Open
Project: Doctrine 2 - ORM
Component/s: None
Affects Version/s: None
Fix Version/s: 2.x
Security Level: All

 Type: Documentation Priority: Major Reporter: Roman S. Borschel Assignee: Jonathan H. Wage Resolution: Unresolved Votes: 0 Labels: None

 Description
 We need a new coding standards document for Doctrine 2.

 Comment by Benjamin Morel [ 29/Jan/13 ] Has there been any work on a coding standards document yet? I'm currently working on fixing documentation on this project, and it might be a good time to define a standard. I've started compiling a few recommendations based on various feedbacks I've got in my pull requests, and I can post them here. Please let me know if there have been previous attempts so far! Comment by Marco Pivetta [ 29/Jan/13 ] Benjamin Morel Guilherme Blanco may have a CS ruleset, but it's not ready yet. Perfect timing btw, we really need to automate this to avoid having all these useless CS fix comments in pull requests Comment by Benjamin Morel [ 29/Jan/13 ] Ok, I'll post my document here once ready, and Guilherme Blanco will be able to compare it with his ruleset! Comment by Benjamin Morel [ 30/Jan/13 ] Here is a first draft: https://gist.github.com/4676670 Please comment! Comment by Benjamin Morel [ 11/Feb/13 ] Guilherme Blanco, if you don't have time to compare your ruleset with my draft, maybe you could publish your current ruleset so that others can have a look? Comment by Benjamin Morel [ 02/Aug/13 ] Any update guys? I'm willing to spend some time on this work, but if no one answers, we won't be going forward Comment by Marco Pivetta [ 02/Aug/13 ] Benjamin Morel I think a pull request against the doctrine website (https://github.com/doctrine/doctrine-website-sphinx) would be fine... Comment by Steve Müller [ 17/Apr/14 ] This should go into https://github.com/doctrine/coding-standard repo (long term).

### [DDC-586] Repo does not find "unflushed" object Created: 14/May/10  Updated: 26/Aug/10

Status: Open
Project: Doctrine 2 - ORM
Component/s: None
Affects Version/s: 2.0
Fix Version/s: None
Security Level: All

 Type: Improvement Priority: Major Reporter: John Kleijn Assignee: Roman S. Borschel Resolution: Unresolved Votes: 0 Labels: None

 Description
 The problem is this: $bar = new \entity\content\ContentTag();$bar->setName('bar'); $em->persist($bar); $existingTag =$em->getRepository('entity\content\ContentTag')->findOneByName('bar'); Seeing as in EntityRepository "find()" queries the Unit of Work first, and "findBy()" goes directly to the persister, only remotely stored objects will be found. Now if I want a tag object to attach related tags, it would have to query by name to see if an object already exist, BUT it wont find one as the UoW has not been committed, resulting in a new one being created, ultimately resulting in a PDO error on the unique name constraint. This can be "solved" by inserting a flush, but it is impossible to know whether a flush is required, without knowledge of what comes next. I.e. for one part to know it has to flush, it has to know another wants to fetch an object you just created. This causes an unacceptable amount of coupling. Somehow the repo will have to be able execute DQL against the objects in the UoW. This does not have to be full support (straight away), but it should fail (throw an exception) if the possibility exists that the UoW contains items that are excluded (e.g. the operation is not supported and the UoW still contains items). For right now, this means the EntityManager should throw an exception if DQL is executed on the type when the UoW is not empty. Until the time that the EntityManager can query the UoW using DQL. The alternative would be to "flush" before every operation that goes to the database for data.

 Comment by Roman S. Borschel [ 14/May/10 ] Hi, you mention a good point, however, this currently only affects findBy queries made through a repository. A DQL query already triggers a flush when there are pending insertions but this still has its own problems. First of, querying against the objects in the UoW is not a viable solution in my eyes. For a regular find() (by identifier) the situation is clear anyway, you must flush prior to a lookup on an entity you previously persisted in the same request because, by definition, generated primary key values are only guaranteed to be available after the next flush. Automatic flushing if the UoW has pending inserts (new objects) and a query is executed (either through DQL or a repository) currently has its own set of problems, namely that it is still subject to infinite recursion if such a query is triggered in an event (listener) that executes during commit of a UoW, and secondly, that it will easily lead to double-flushes that cause unnecessary overhead (currently a flush() even if nothing needs to be done is not free because the UoW actually has to check whether nothing needs to be done). Both of these problems could be addressed with some sort of flags, but the question still is whether its not better to flush manually in the first place. That would mean, in your example, you should flush after persisting the new objects, irrespectively of what code comes next, you persisted (a) new object(s) and you want to make sure these are fully available to the rest of the script. Comment by Roman S. Borschel [ 14/May/10 ] Furthermore, automatic flushing when there is no transaction active is probably also not a great idea, as it may split a single unit of work (that was supposed to be atomic) into 2 without the user knowing about it. So auto-flushing should better only happen when a transaction is active (i.e. explicit transaction demarcation is used). Comment by John Kleijn [ 14/May/10 ] That would mean, in every example, you should flush after persisting new objects, period. If I flush in some cases and not in others, I'm asking for issues that may not be caught by tests. It's an inconsistency that I personally am not comfortable with. Could be that I'm overlooking something, I've just started playing with D2. Why is querying against registered objects not viable? It's not easy, granted, but it doesn't seem impossible. There should probably be a layer between the UoW and the "persisters" (Data Mappers?). RE: the UoW double flush: state management on the UoW as a whole should prevent that. i.e. after a commit the whole UoW is clean? Just a suggestion, as I said, still getting my bearings. On a side note I just want to say that what I've seen so far, for the better part, pleases me greatly. Kudos. Comment by Roman S. Borschel [ 14/May/10 ] @"That would mean, in every example, you should flush after persisting new objects, period." Yes, if you want the objects to be visible to queries in the same request. Generally, you should flush when you complete a unit of work and that is usually not the whole request (but can be). I don't want to "query" against registered objects because it is a) not easy b) likely a lot of code and c) very likely error-prone. And in addition I don't see this helping with solving any inconsistency. If you want to use find() you have to flush anyway because you can not find() without having the identifier in the first place, which is only available after a flush. @RE: the UoW double flush: Yes, like I said, it can be done but it is a compromise. Having a "clean/dirty" flag in addition to calculating the changesets of the work to do (which implicitly tells us whether the UoW is dirty) adds more code and more potential for errors. Forget to update the flag in one location and you get flushes that don't do anything, because the flag was not updated. A dirty-flag for the UoW is not really required for proper working. It is similar to the approach of maintaining a separate counter for the number of elements in a collection implementation: can make many size/count requests faster but complicates the internal implementation and increases the likelihood for errors (and lock contention for the counter in a thread-safe/concurrent implementation, an interesting case where performance goes against scalability, but I digress and that does not apply to php obviously). That said, I am not strongly opposed to doing this. If you're interested in how this is specified by "big brother", take a look at section 3.8.7 of the JPA 2 specification. Shortly, with the default behavior it requires the implementation to ensure that unflushed changes are visible to queries which can be achieved by flushing these to the database automatically but only if a transaction is active, otherwise the implementation must not flush to the database. There is alternatively also a "MANUAL" flush mode, in that case the effect of updates made to entities in the UoW upon queries is unspecified. We do not have different flush modes anymore, however, in Doctrine. So I see two possible ways to go here: 1) More effort, more code, (really better?) Maintaining a dirty flag in the UoW (this could be done anyway at some point, even if 2) is chosen) Maintaining a flag to avoid infinite recursion triggered from events within a UoW commit/flush Flushing automatically when querying while there are pending inserts and a transaction is active 2) No effort, less code Removing the current auto-flush on DQL queries which is still subject to infinite recursion No automatic flushes, anywhere (less magic, so to speak?) Clearly documenting that new, unflushed entities are not visible in subsequent queries issued in the same request, and if this is desired, a flush should be issued. That's how I see it. Now we need some votes and volunteers for the implementation Personally, I am not sure yet about which version I prefer, 2) does not sound too bad for me. Comment by Roman S. Borschel [ 14/May/10 ] In Nr. 1) the case with the infinite recursion may actually be more problematic. I think you simply can not see unflushed new objects in queries made during a UoW commit. Comment by John Kleijn [ 14/May/10 ] When there's no in-memory objects inclusion, I'd say 2) as well. Again, I have no idea how this is implemented currently, but I would prefer something like this: $repo->start();$repo->register($object);$repo->commit(); Why? Commit instead of flush: "flush" has little semantic value IMO, "commit" leaves no questions: you're committing your changes (which implies that they are not, before) Operating on the repo leaves no question to what you are committing: changes of the associated type and relations configured to cascade, made after start() Register instead of persist: "persist" is misleading as the object is not immediately persisted, and as my example shows, may not be. The way I see it "start" would create a UoW associated with the repo, "commit" would calculate changes and write (the enitity manager would make sure references in other UoWs are removed). Because the way it is currently implemented (or so it seems), it's unclear when to flush and when not to flush, and unclear what I'm flushing at any one point in the code (because it is not locally isolated). If I have to decide whether to flush in some bit of client code, I am apparently making an assumption about the target entity, i.e. coupling. I know, you already went beta, so it's unlikely you would consider such a large change, but anyway, for your consideration. Finally, I realize I'm borderline nagging now as you've made it clear you see nothing it, but a Repository (as in the PoEAA pattern, p 322) may provide a method of fetching native in-memory objects using criteria, acting as a "buffer" between code and database. The Repository in D2 does effectively nothing but delegate to the UoW (or mostly to the underlying persister). Ref PoEAA 327 for an example of an in-memory strategy. As a final point of critique, the Repository does not always seem to be used as entry point for data requests, which is the whole point of the pattern. Most of what's in EntityManager, should be in EntityRepository ("manager" is a bit to abstract a concept to expect clear responsibilities anyway). EntityManager::find() delegates to EntityRepository, but pretty much everything else is the other way around. EntityManager would be better off named DataGateway, as that accurately describes its intended function. I admit, it would be very difficult to use DQL on in memory objects, but it would be far superior and if it work lead to much more predictable behaviour. It's the ONLY way the data store is ever going to be truly transparent. A few examples (DQL from the docs): SELECT u, UPPER(u.name) nameUpper FROM MyProject\Model\User u Fetch everything from the db Select all objects from the User UoW Iterate over the in memory ones and modify the name property to upper case Merge the results and return SELECT u FROM User u WHERE u.id = ?1 OR u.nickname LIKE ?2 ORDER BY u.surname DESC Execute against database Iterate over the User UoW, indexing by "surname", adding items that match the criteria Merge the results and return With joins it could get more complex, provided you want to intelligently merge results into existing objects. Question is whether that is really needed, but there's obviously a performance benefit. Actually this may already be implemented. I suspect there are edge cases, rooted in DQL still being based on SQL, but in theory it should be possible. Likely you would still want to do start(), and delegate to the driver to start an actual transaction to prevent inconsistent reads... The only way to find out if it's truly feasible is to to try it, I think. Ramble, ramble, ramble, I'm done. I know I seem critical, but it's positive critique, I love the direction you went with D2. Comment by Roman S. Borschel [ 14/May/10 ] Maybe I was not clear, with approach Nr.1 there would be in-memory objects inclusion (of new objects), in fact, there always is, due to the identity map. When you query for objects and some of them are already in memory, these are used, not again reconstructed. The EntityRepository provided by Doctrine is just a convenient mechanism for writing your own repositories. There are many different understandings for what a repository is, you can make it whatever you want it to be. Is a PoEAA repository the same as a DDD repository? Anyway, the repository could be stripped of the project, it is optional, the state management is handled by the EntityManager and UnitOfWork. These are the core components. I agree that the delegation from EntityManager#find to the repository is suboptimal in this regard and should be the other way around. Now to your question: "When should I flush?". Generally, you should flush at the end of a transaction, which in turn is a unit of work. That means, use explicit transaction demarcation. begin() ... flush() commit(). I've added some control abstractions recently that should make this even easier. I can only recommend to explicitly demarcate your transaction boundaries. As you probably know, you can not talk to your database outside of a transaction anyway. The default behavior (flush() wrapping all its stuff in a transaction) is for convenience mostly and so as not to alienate or confuse people even more who are used to autocommit mode. Concerning the naming, we mostly stick with the JPA specification and I, for one, really like the naming and I don't want to invent new names. PoEAA is far more abstract (and the examples far too specific) than what is specified in JPA, so I recommend giving that a read. The patterns in PoEAA obviously and intentionally leave a lot of room for different variants of implementation and also leave open a lot of open questions (many of the difficult questions especially, it is for a reason that the author recommends using an existing tool instead of writing your own). In my opinion it is just not feasible to query in-memory objects in a generic way, all the examples in PoEAA do not have generic but rather concrete code examples, which is obviously a lot easier. The feasible strategy, and that is what we do, is to do in-memory lookups only when querying by PK, otherwise the query is executed and afterwards nevertheless any objects reused that are already in memory (based on the PK) and not reconstructed. This is the approach we use. Thanks for your input, I do see that you are an experienced fellow in object-relational persistence, maybe we can see you as a committer some day? Comment by Roman S. Borschel [ 14/May/10 ] @ "SELECT u, UPPER(u.name) nameUpper FROM MyProject\Model\User u" This selects all users and their names in uppercase, the uppercase names are scalar values, the users are not modified! Scalar values are separate from objects. @ "... and unclear what I'm flushing at any one point in the code" flush() means: Synchronize the in-memory state of my objects with the database, making any changes that are only in-memory persistent. Nothing more, nothing less. Again, objects are always reused based on the identity map and the state that is in-memory prevails, unless you use refresh() or execute a query with the Query::HINT_REFRESH query hint. All objects you fetch from DQL, be it as a root object or as a joined association, are first looked up in-memory (but after the SQL query has been issued!). Maybe we have been talking past each other here, what I refer to as not feasible is querying the in-memory objects first in some way, even before the SQL query. This is just too complicated and error-prone, except for the simple case of a PK lookup and that is where we do it already. Comment by John Kleijn [ 14/May/10 ] > Scalar values are separate from objects. Right. Bad example. > flush() means: Synchronize the in-memory state of my objects with the database, making any changes that are only in-memory persistent. Nothing more, nothing less. I realize that it means that, but commit() would be more obvious. > Maybe we have been talking past each other here, what I refer to as not feasible is querying the in-memory objects first in some way, even before the SQL query. This is just too complicated and error-prone, except for the simple case of a PK lookup and that is where we do it already. Fair enough, you don't think it's feasible, so we'll keep it at that. Maybe I'll give it a shot some time.

### [DDC-624] Partial object query that leaves out an association to avoid loading it fetches the association anyway. Created: 03/Jun/10  Updated: 11/Nov/11

Status: Open
Project: Doctrine 2 - ORM
Component/s: None
Affects Version/s: 2.0-BETA1
Fix Version/s: 2.x
Security Level: All

 Type: Bug Priority: Major Reporter: Roman S. Borschel Assignee: Roman S. Borschel Resolution: Unresolved Votes: 2 Labels: None

 Duplicate is duplicated by DDC-1465 Fetching partial objects doesn't work... Open

 Description
 Assuming: Customer Cart where Cart is the owning side. Since the association from Customer to Cart can not be lazy, it would make sense to leave out the association in a query to avoid loading the carts like this: select partial c.{id,name, ... anything except cart} from Customer c"  But this is ignored and the carts of all customers are fetched anyway. Query::HINT_FORCE_PARTIAL_LOAD is an alternative solution, however it has the disadvantage that it disables lazy-loading for all queried objects. If partial querying would honor associations this would allow more fine-grained control.

 Comment by Roman S. Borschel [ 26/Aug/10 ] Might need to be pushed back to a 2.0.x / 2.x.x bugfix release. Not clear yet.

Allow @Id on @ManyToOne fields (DDC-117)

### [DDC-658] Reverse engineering with Oracle (DBDriver and Associations as Identifier) Created: 27/Jun/10  Updated: 11/Dec/11

Status: Open
Project: Doctrine 2 - ORM
Component/s: ORM
Affects Version/s: None
Fix Version/s: 2.x
Security Level: All

 Type: Sub-task Priority: Major Reporter: Mickael Perraud Assignee: Benjamin Eberlei Resolution: Unresolved Votes: 1 Labels: None Environment: Ubuntu 10.04 + Oracle 11g Entreprise + PHP 5.3.2 + Doctrine2 Git (up-to-date)

 Description
 I am playing with reverse engineering with Oracle and I have some problems: My schema: drop table PHONE_NUMBER; drop table CUSTOMER; create table CUSTOMER ( CUSTOMER_ID NUMBER(4) not null, CUSTOMER_LASTNAME VARCHAR2(50) not null, CUSTOMER_MODIFIED DATE, constraint PK_CUSTOMER primary key (CUSTOMER_ID) using index tablespace TBS_INDEX storage ( initial 100K next 100K ) ) storage ( initial 100K next 100K ) tablespace TBS_DATA; create table PHONE_NUMBER ( PHONE_NUMBER_ID NUMBER(4) not null, CUSTOMER_ID NUMBER(4) not null, PHONE_NUMBER VARCHAR2(50) not null, PHONE_NUMBERMODIFIED DATE, constraint PK_PHONE_NUMBER primary key (PHONE_NUMBER_ID, CUSTOMER_ID) using index tablespace TBS_INDEX storage ( initial 100K next 100K ) ) storage ( initial 100K next 100K ) tablespace TBS_DATA; alter table PHONE_NUMBER add constraint PHONE_NUMBER__CUSTOMER foreign key (CUSTOMER_ID) references CUSTOMER (CUSTOMER_ID);  I obtain "Fatal error: Uncaught exception 'Doctrine\ORM\Mapping\MappingException' with message 'Property "customerId" in "PhoneNumber" was already declared, but it must be declared only once'" It's because a foreign key is a component of the primary key.

 Comment by Mickael Perraud [ 28/Jun/10 ] This is the continuation of http://www.doctrine-project.org/jira/browse/DDC-616. Only the schema is different. Comment by Benjamin Eberlei [ 28/Jun/10 ] just for understanding this scenario: Is this a One-To-One relation and the TABLE_TEST2 "inherits" the primary key from its parent TABLE_TEST1? If yes, this construct is not yet supported by Doctrine 2, we still need to include an ID-Generator that supports this kind of schema. Comment by Mickael Perraud [ 28/Jun/10 ] Change for a more understandable use case. Note that it's not my real use case and that I work on legacy database on which I can't change the structure. Comment by Benjamin Eberlei [ 01/Jan/11 ] updated the issue topic to get a better grasp of what needs to be done here. Comment by waldo [ 09/Jun/11 ] I have the same error with Mysql whit the same condition. Comment by Benjamin Eberlei [ 28/Nov/11 ] More details on the work to be done: The relevant code is in Doctrine/ORM/Mapping/Driver/DatabaseDriver.php only. The idea is currently many-to-many tables are detected by checking that the table has foreign keys on all the primary key columns (no additional columns!) Now with the 2.1 feature of foreign key/primary key entities this is not necessarily true anymore. You can have the primary keys being foreign keys BUT have additional columns that are not part of the primary key. This has to be detected. If a foreign key-primary-key entity is found that has additional columns a ClassMetadata has to be created and the associations have to be created with the "id" => true flag in mapManyToOne(). Comment by Scott Steffens [ 11/Dec/11 ] For what it's worth, I'm getting this error when I have a PK that is a single column and not a FK. PRIMARY KEY (id), UNIQUE KEY cycle_station_id (cycle,station_id), KEY station_id_idx (station_id), KEY readings (readings), KEY source (source), KEY temperature_min_max (temperature_max,temperature_min), KEY station_id_cycle (station_id,cycle,updated_at), CONSTRAINT compiled_1_station_id_stations_id FOREIGN KEY (station_id) REFERENCES stations (id), CONSTRAINT compiled_1_station_id_stations_id_1 FOREIGN KEY (station_id) REFERENCES stations (id) ON DELETE CASCADE ) ENGINE=InnoDB AUTO_INCREMENT=160833690 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci

### [DDC-667] Lock Timeout Query Hint for DQL Queries Created: 04/Jul/10  Updated: 16/Sep/10

Status: Open
Project: Doctrine 2 - ORM
Component/s: ORM
Affects Version/s: 2.0-BETA2
Fix Version/s: 2.x
Security Level: All

 Type: New Feature Priority: Major Reporter: Benjamin Eberlei Assignee: Benjamin Eberlei Resolution: Unresolved Votes: 0 Labels: None

 Description
 After the implementation of DDC-178 there is now only outstanding the support for locking queries based on a given timeout. This will be a DQL query feature only and be available via a query hint: $query->setHint(Query::LOCK_TIMEOUT,$timeoutMs);  It will be only working on Oracle.

 Comment by Roman S. Borschel [ 30/Aug/10 ] If this is to be implemented for 2.0, it needs to happen for RC1, therefore rescheduling to RC1. Feel free to reschedule to 2.x if necessary. Comment by Benjamin Eberlei [ 16/Sep/10 ] Only oracle supports lock timeouts and no other vendor seems to plan to support it. I move to 2.x, but i guess this would rather be an issue of user extension.

### [DDC-668] add upsert support Created: 04/Jul/10  Updated: 20/Dec/11

Status: Open
Project: Doctrine 2 - ORM
Component/s: ORM
Affects Version/s: None
Fix Version/s: 2.x
Security Level: All

 Type: New Feature Priority: Major Reporter: Lukas Kahwe Assignee: Benjamin Eberlei Resolution: Unresolved Votes: 4 Labels: None

 Description
 Didnt find anything in the docs on this. Is D2 capable of doing an UPSERT [1] in case I am trying to persist an object that may or may not have been saved previously. Different RDBMS support different syntax for this case. Like MySQL has INSERT .. ON DUPLICATE KEY UPDATE (or even INSERT IGNORE) while the SQL standard defines a MERGE syntax which seems to be gaining support. Of course you can always fallback to a SELECT FOR UPDATE (or if you want to be hacky an INSERT which catches duplicate key violations .. but probably not a good idea since many RDBMS rollback on a failure inside a transaction). See also http://opensource.atlassian.com/projects/hibernate/browse/HHH-3011 asking for MERGE support Ideally there would be a way to define on a model or model instance level if merge logic should be applied.

 Comment by Robert Burkhead [ 09/Jul/10 ] Doctrine_Record defines a replace() method. In the MySQL Doctrine implementation, however, it is not the same as INSERT .. ON DUPLICATE KEY UPDATE. The replace() method implemented in Doctrine_Connection_Mysql uses the REPLACE INTO syntax, which is a DELETE and then INSERT when the key exists. This is fine, except for tables that use auto-increment fields. The delete-then-insert operation yields a new auto-incremented value, whereas INSERT .. ON DUPLICTATE KEY UPDATE would not. Comment by Lukas Kahwe [ 09/Jul/10 ] MySQL (and SQLite) REPLACE is a no go. It causes way too much disc I/O and worse yet totally screws up the on disk data structures because of the deleting. Comment by Benjamin Eberlei [ 31/Jul/11 ] Scheduled for 2.2 Comment by Benjamin Eberlei [ 31/Jul/11 ] Evaluating this makes me sad, except MySQL support for this is rather non-existant, and the oracle merge is aiming at batch operations. Comment by Benjamin Eberlei [ 22/Oct/11 ] Should this be done with 1. Select first, then insert 2. Catch and evaluate exception then update I am leaning towards 1. Comment by Guilherme Blanco [ 20/Dec/11 ] Updating fix version

### [DDC-676] Find a way to test serialize/unserialize of all ClassMetadata properties in isolation Created: 10/Jul/10  Updated: 29/Aug/10

Status: Open
Project: Doctrine 2 - ORM
Component/s: ORM
Affects Version/s: None
Fix Version/s: 2.x
Security Level: All

 Type: Improvement Priority: Major Reporter: Benjamin Eberlei Assignee: Benjamin Eberlei Resolution: Unresolved Votes: 0 Labels: None

 Description
 We should find a way, using PHPUnit Data Providers or anything else, to check the serialize/unserialize of every property in the ClassMetadata instance, since errors here can be very subtle but dangerous.

### [DDC-678] OneToMany/OneToOne + onDelete=CASCADE may corrupt UoW. Created: 10/Jul/10  Updated: 05/Jun/11

Status: Open
Project: Doctrine 2 - ORM
Component/s: None
Affects Version/s: None
Fix Version/s: None
Security Level: All

 Type: Improvement Priority: Major Reporter: Roman S. Borschel Assignee: Roman S. Borschel Resolution: Unresolved Votes: 0 Labels: None

 Description
 OneToMany/OneToOne associations together with an onDelete=CASCADE schema generation hint on the @JoinColumn and appropriate foreign key constraints can potentially result in a corrupt UoW if the associated objects are already managed. We need to add tests for such scenarios and settle on a well-defined behavior in such cases.

 Comment by Benjamin Eberlei [ 31/Oct/10 ] I think to preserve the semantics the following has to happen: "on-delete" => "cascade" has to implicitly set cascade = remove. This hurts performance of course vs just using the on-delete, however it won't corrupt the UoW. Comment by Benjamin Eberlei [ 02/Jan/11 ] Not entirely would it hurt performance, you could check if on-delete => cascade is set. If this is the case you wouldnt need to do an explicit remove using the UnitOfWorks cascade. Comment by Benjamin Eberlei [ 05/Jun/11 ] Changed to improvement

### [DDC-683] EntityManager#lock() on unitialized proxy coudl be optimized Created: 10/Jul/10  Updated: 21/Jul/10

Status: Open
Project: Doctrine 2 - ORM
Component/s: ORM
Affects Version/s: 2.0-BETA2
Fix Version/s: None
Security Level: All

 Type: New Feature Priority: Major Reporter: Benjamin Eberlei Assignee: Benjamin Eberlei Resolution: Unresolved Votes: 0 Labels: None

 Reference relates to DDC-681 PATCH: UnitOfWork#lock locks by colum... Resolved

 Description
 If you call lock() on an unitiialized proxy, it would be possible to combine the fetch and lock in one operation. Is this feasible from a technical / workflow perspsective?

 Comment by Benjamin Eberlei [ 21/Jul/10 ] Ok this is what refresh() with LOCK support is actually needed for:  public function lock($entity,$lockMode, $lockVersion = null) { if ($this->getEntityState($entity) != self::STATE_MANAGED) { throw new InvalidArgumentException("Entity is not MANAGED."); } else if ($entity instanceof Proxy && $entity->__isInitialized__) {$this->refresh(....); // with LOCK! } ... } 

### [DDC-688] Original Entity Data gets overridden by the change set Created: 12/Jul/10  Updated: 28/Dec/10

Status: Open
Project: Doctrine 2 - ORM
Component/s: ORM
Affects Version/s: 2.0-BETA2
Fix Version/s: None
Security Level: All

 Type: Improvement Priority: Major Reporter: Jasper Kuperus Assignee: Roman S. Borschel Resolution: Unresolved Votes: 0 Labels: None Environment: Mac OS X 10.6; PHP 5.3.2; MySQL 5.1.44

 Description
 When changing data in an entity, the UnitOfWork will call computeChangeSet on a flush event. If there is a changeset, the original data ($this->_originalEntityData) gets overridden by the new data. However, the _originalEntityData should hold the original data, that was present at the time the entity was reconstituted from the database. This does no longer hold now. I think this can simply be fixed by commenting this line, however I do not know of any consequences this may bring with it:$this->_originalEntityData[$oid] =$actualData; (in computeChangeSet, after if( $changeSet )); Anyway, I ran into this problem while trying to retrieve the original data at the onFlush event of an update.  Comments  Comment by Roman S. Borschel [ 08/Aug/10 ] This is actually currently expected. You can not get access to the original data in the onFlush event right now. I'm not saying that this will never be possible but it is simply the way it works at the moment. Comment by Jasper Kuperus [ 08/Dec/10 ] Does this mean that it is currently impossible to implement a Versionable mechanism using snapshots? Comment by Benjamin Eberlei [ 09/Dec/10 ] You can hold a map of them yourself if your listener also implements the "postLoad" event: $entity = $args->getentity();$this->originalData[spl_object_hash($entity)] =$args->getEntityManager()->getUnitOfWork()->getOriginalData($entity);  Comment by Benjamin Eberlei [ 28/Dec/10 ] Changed into possible improvement for the future ### [DDC-726] DQL should deal correctly with composite primary keys Created: 30/Jul/10 Updated: 04/Oct/11 Status: Open Project: Doctrine 2 - ORM Component/s: DQL Affects Version/s: None Fix Version/s: None Security Level: All  Type: Improvement Priority: Major Reporter: Guilherme Blanco Assignee: Guilherme Blanco Resolution: Unresolved Votes: 1 Labels: None Issue Links:  Duplicate is duplicated by DDC-1162 Add support for multi-column IN state... Resolved  Description  DQL should deal correctly with composite primary keys: SELECT u FROM User u WHERE u.CompositeAssocEntity = ?1 Should be converted to: SELECT ... FROM users u WHERE (u.cae_id1, u.cae_id2) = (?, ?) // or something similar  It also supports IN expressions: SELECT u FROM User u WHERE u.CompositeAssocEntity IN (?1, ?2) Should be converted to: SELECT ... FROM users u WHERE (u.cae_id1, u.cae_id2) IN ((?, ?), (?, ?)) // or something similar  MySQL, SQLite and PgSQL works smoothly. Need to check out MSSQL, Oracle and DB2. ### [DDC-763] Cascade merge on associated entities can insert too many rows through "Persistence by Reachability" Created: 23/Aug/10 Updated: 04/Jul/11 Status: Open Project: Doctrine 2 - ORM Component/s: ORM Affects Version/s: None Fix Version/s: 2.x Security Level: All  Type: Improvement Priority: Major Reporter: Dave Keen Assignee: Benjamin Eberlei Resolution: Unresolved Votes: 2 Labels: None  Attachments: 0149-DDC-763.patch DDC763Test.php multipleaddmerge.diff  Description  I think that the UnitOfWork needs to maintain a map of spl_object_hash($newEntity)->$managedEntity for entities that were persisted via reachability during a merge. doMerge should then only call persistNew if the original entity has not already been persisted (if it has already been persisted it should merge the managed entity from the map). The map should be maintained until a flush() or until the UnitOfWork is cleared. The reasoning is as follows. Imagine we have a simple doctor object with no associations: $doctor = new Doctor(); $em->persist($doctor); $em->persist($doctor); $em->flush();  After the first persist()$doctor is MANAGED so the second persist has no effect and this results in a single Doctor row. If we do the same thing using merge and persistence by reachability: $doctor = new Doctor();$em->merge($doctor);$em->merge($doctor);$em->flush();  we get 2 Doctor rows being added. Obviously in this particular case we should use the return value from the first merge() as the parameter of the second merge which would give correct behaviour. However, now imagine one Doctor has many Patients and many Patients have one Doctor, all the associations have cascade merge enabled, and further assume that $d1 (Doctor id=1) is already in the database. We now attempt to create two patients and assign them to the existing doctor: $d1= new Doctor(); $d1->id = 1; // This is a DETACHED entity$p1 = new Patient(); $p2 = new Patient();$d1->patients->add($p1);$p1->doctor = $d1;$d1->patients->add($p2);$p2->doctor = $d1;$em->merge($p1);$em->merge($p2);$em->flush();  This actually results in 4 rows being added to the 'patients' table instead of 2, I think because $p1 and$p2 are getting persisted both as the root objects and then again from the patient->doctor->patients array. Since the cascade merging happens internally we can't replace the array contents with the managed return values without walking through the object graph (in which case there is no point in using cascade merge in the first place). Maintaining a map in UnitOfWork will allow doMerge to ensure it doesn't persist the same entities twice. I'm not sure, but this might be relevant for cascade persist too. P.S. Another bug report on this can be found at http://code.google.com/p/flextrine2/issues/detail?id=32 (it basically says the same thing with different entities).

 Comment by Benjamin Eberlei [ 29/Aug/10 ] @Roman A possible fix for this in my opinion is another map in UnitOfWork $mergedEntities = array(); and a patch like this: diff --git a/lib/Doctrine/ORM/UnitOfWork.php b/lib/Doctrine/ORM/UnitOfWork.php index 242d84b..1d0d8b3 100644 --- a/lib/Doctrine/ORM/UnitOfWork.php +++ b/lib/Doctrine/ORM/UnitOfWork.php @@ -1340,6 +1340,10 @@ class UnitOfWork implements PropertyChangedListener return; // Prevent infinite recursion } + if (isset($this->mergedEntities[$oid])) { + return$this->mergedEntities[$oid]; + } +$visited[$oid] =$entity; // mark visited $class =$this->em->getClassMetadata(get_class($entity)); @@ -1468,6 +1472,8 @@ class UnitOfWork implements PropertyChangedListener$this->cascadeMerge($entity,$managedCopy, $visited); +$this->mergedEntities[$oid] =$managedCopy; + return $managedCopy; }  Comment by Dave Keen [ 29/Aug/10 ] I have tested this patch with my application and it fixes the problem in all my relevant test cases apart from one. The test case that's failing is one that persists a bi-directional many to many relationship, so the associations interweave with each other (if you know what I mean). I wonder if perhaps doMerge need to continue cascading even if it finds an item in$this->mergedEntities This is the Flextrine code that fails - it results in no entries in movie_artist. This might also be related to DDC-758? m1 = new Movie(); m1.title = "Movie 1"; m2 = new Movie(); m2.title = "Movie 2"; a1 = new Artist(); a1.name = "Artist 1"; a2 = new Artist(); a2.name = "Artist 2"; m1.artists.addItem(a1); a1.movies.addItem(m1); m1.artists.addItem(a2); a2.movies.addItem(m1); m2.artists.addItem(a1); a1.movies.addItem(m2); m2.artists.addItem(a2); a2.movies.addItem(m2); // These translate to cascade merges on the server em.persist(m1); em.persist(m2); em.persist(a1); em.persist(a2); // Now flush em.flush(); Comment by Dave Keen [ 29/Aug/10 ] P.S. This test passes if I translate em.persist() to $em->persist() (not cascading) on the server instead of translating it to a cascade merge; not sure if that helps Comment by Roman S. Borschel [ 30/Aug/10 ] I'd really like to avoid introducing an additional instance variable just to solve this issue but I did not find the time yet to really look into it. Does someone have a unit test for this already and can attach it to the issue? Comment by Roman S. Borschel [ 31/Aug/10 ] Rescheduling for RC1. Comment by Dave Keen [ 13/Sep/10 ] Here is a functional test case containing three tests: testMultiMerge tests basic merging of two new entities, checking that only a single entity ends up in the database. This passes with Benjamin's patch. testMultiCascadeMerge tests the more complex case of merging a OneToMany association. This also passes with Benjamin's patch. testManyToManyPersistByReachability tests the ManyToMany case described above and this fails with Benjamin's patch, probably because doMerge doesn't cascade down entities that it has already merged and some ManyToMany associations are being ignored. Its a bit hard to be certain what is causing this as even without Benjamin's patch this test would fail due to DDC-758. Comment by Benjamin Eberlei [ 15/Sep/10 ] @Roman i thought about this issue, its not possible without that additional map of merged entities. There is no way we can get that information from other sources. Problem is rather that the use-case probably only applies in mass-merging scenarios and client-server serialization. Comment by Dave Keen [ 21/Sep/10 ] Added another failing test case - adding the same entity from different ends of a many to many bi-directional association to check that there isn't an integrity constraint violation caused by Doctrine trying to add the same row twice. Comment by Dave Keen [ 21/Sep/10 ] Attached a patch for this issue. Comment by Benjamin Eberlei [ 22/Sep/10 ] can you comment why all the additionall stuff is necessary compared to my patch? Comment by Dave Keen [ 22/Sep/10 ] It fixes the two additional test cases - testManyToManyPersistByReachability and testManyToManyDuplicatePersistByReachability. testManyToManyPersistByReachability was failing with your original patch because there are ManyToMany cases where an entity may have already been merged, but its still necessary to add it to an association and continue to cascade. Running the following with the original patch will miss out some of the associations. $m1 = new Movie(); $m1->title = "Movie 1";$m2 = new Movie(); $m2->title = "Movie 2";$a1 = new Artist(); $a1->name = "Artist 1";$a2 = new Artist(); $a2->name = "Artist 2";$m1->artists->add($a1);$a1->movies->add($m1);$m1->artists->add($a2);$a2->movies->add($m1);$m2->artists->add($a1);$a1->movies->add($m2);$m2->artists->add($a2);$a2->movies->add($m2);$em->merge($a1);$em->merge($a2);$em->flush();  The other change in my patch is to protect against this case. It ensures that the following code doesn't add the same entity twice to a collection. $em->merge($m1); $em->merge($m2); $em->merge($a2); $em->merge($a2); $em->flush();  Comment by Benjamin Eberlei [ 31/Oct/10 ] I am not sure if the issue here is rather multiple calls to merge that contain different parts of the same object-graph. There should be a very simple fix for this, call ->clear() after each merge. I am not sure if this patch drags us into a blackhole of issues with merging. Comment by Dave Keen [ 31/Oct/10 ] Calling ->clear() and ->flush() after each merge is a workaround for the simple case, but unless I am misunderstanding I don't think its a solution for cases where the merging is happening automatically in cascadeMerge. I've actually encountered this issue in another project and scenario to do with creating REST APIs and merging JSON objects into entities, and applying the patch fixed it so a) I think this issue might be a more common that we first thought and b) the patch basically seems to work (plus it doesn't introduce any failing cases in the existing test suite). I can actually still find one edge case to do with cascading merging interlinked many to many associations that this doesn't fix, but I was planning to open that as a new ticket after this My feeling is that the current merge already has issues and this definitely improves it. Comment by Benjamin Eberlei [ 01/Nov/10 ] It cannot happen inside a single merge, single merges use the$visited to avoid infinite recursions, each entity can only be merged once inside a single merge operation. Comment by Benjamin Eberlei [ 10/Nov/10 ] Added a note into the documentation about using EntityManager#clear between merging of entities which share subgraphs and cascade merge. Handling this issue in UnitOfwork will be declared an improvement, not a bug anymore and be scheduled for later releases. The required changes to the core are to dangerous and big. Comment by Dave Keen [ 11/Nov/10 ] Where in the docs is that? Just to summarize, the equivalent operation to having multiple merges and a single flush is to call merge followed by flush each time, with the whole thing surrounded by a transaction? Does this have a big impact on performance? Comment by Dave Keen [ 11/Nov/10 ] Ben - even given the decision not to implement this (and I do understand your thinking, as it is a major change), is there any reason not to implement the bit that ensures that the same entity isn't added to a collection twice during a merge? I can't think of a situation where this should be allowed, and I have a use case where I get 'DUPLICATE KEY' errors if this isn't there. Please see attached patch. Comment by Benjamin Eberlei [ 11/Nov/10 ] What bit of that huge patch is that? Can you extract it into another ticket if thats possible? Comment by Benjamin Eberlei [ 11/Nov/10 ] I added it to "Working with Objects" and the descripton of Merge. Its not yet live on the site. Using this current workaround has a performance impact, since more SELECT statements have to be issued against the database. Comment by Dave Keen [ 11/Nov/10 ] Apologies for not being clear - only the 3rd patch (multipleaddmerge.diff) is relevant to the 'DUPLICATE KEY' error I am now talking about, but I'll put it in a nother ticket if you prefer. Comment by Benjamin Eberlei [ 11/Nov/10 ] please add a new ticket, patch looks good. Comment by Dave Keen [ 11/Nov/10 ] Created as DDC-875

### [DDC-769] Disabling discriminator column in WHERE clause Created: 26/Aug/10  Updated: 07/Sep/10

Status: Open
Project: Doctrine 2 - ORM
Component/s: None
Affects Version/s: 2.0-BETA3
Fix Version/s: None
Security Level: All

 Type: Improvement Priority: Major Reporter: Lars Strojny Assignee: Roman S. Borschel Resolution: Unresolved Votes: 1 Labels: None

 Description
 Per default Doctrine 2 adds an IN(...)-part to the query when hydrating an entity where a discriminator column is defined. While this makes sense as a default behavior, it would be pretty helpful if one could disable the WHERE-clause for discriminator columns alltogether for performance optimization.

 Comment by Roman S. Borschel [ 26/Aug/10 ] That would obviously produce wrong results. Maybe you can elaborate more with an example. Comment by Lars Strojny [ 07/Sep/10 ] I use ENUM("foo","bar") as discriminator columns. That means, the column will contain the right values out of the box, no further result set limiting required with WHERE.

### [DDC-776] Persisters use a fixed "SELECT" SQL statements Created: 29/Aug/10  Updated: 23/Apr/13

Status: Open
Project: Doctrine 2 - ORM
Component/s: None
Affects Version/s: 2.0-BETA3
Fix Version/s: None
Security Level: All

 Type: Improvement Priority: Major Reporter: Aaron DM Assignee: Roman S. Borschel Resolution: Unresolved Votes: 0 Labels: None Environment: Windows 7, Apache 2.2, MSSQL Server, PHP 5.3.3

 Description
 I am currently trying to work with BINARY columns with Doctrine 2 and MSSQL. In order to get my Entities working I had to create a custom Mapping Type for Binary columns. All went well in this case and I've got it running. The problem arises when I am attempting to use Associative mapping (OneToOne/ManyToMany). The problem is, in order to do a select for an SQL column, I had to create a DQL function called "CONVERT" so that I use WHERE statements: return $this->createQueryBuilder('u') ->where("u.id = CONVERT('binary', :id, 1)") ->setParameter('id',$id) ->getQuery() ->getSingleResult(); As you see, I must do this in order to get a result. However, when I'm using associative mapping; this is what it does: return 'SELECT ' . $this->_getSelectColumnListSQL() . ' FROM ' .$this->_class->getQuotedTableName($this->_platform) . ' ' .$this->_getSQLTableAlias($this->_class->name) .$joinSql . ($conditionSql ? ' WHERE ' .$conditionSql : '') . $orderBySql .$lockSql; As you can see, its some what hard coded and I cannot change it without changing the actual code in Doctrine\ORM\Persisters\BasicEntityPersister.php So, I would first like to know if there was maybe a way you could allow us to customize the SELECT statement that the persisters use - or maybe (though I'm not sure how this will be done) make them use user-defined repository functions? Like $myRepo->find($identifier) Not entirely sure if I explained this properly and I do realize my circumstance is highly odd - but this does seem like a limitation and because of this I cannot use associative mapping.

 Comment by locs [ 23/Apr/13 ] Hi, i try to make my custom type for binary field in MSSQL. I don't find own, can you please show me your custom type binary? Thks a lot.

### [DDC-779] Doctrine\ORM\Configuration should be immutable after construction of EntityManager Created: 30/Aug/10  Updated: 30/Aug/10

Status: Open
Project: Doctrine 2 - ORM
Component/s: ORM
Affects Version/s: 2.0-BETA3
Fix Version/s: None
Security Level: All

 Type: Improvement Priority: Major Reporter: Benjamin Eberlei Assignee: Roman S. Borschel Resolution: Unresolved Votes: 0 Labels: None

 Description
 Currently the Doctrine\ORM\Configuration instance is not immutable after construction of the EM, which can lead to funny behavior when changing essential dependencies such as caches or others.

### [DDC-785] Post-Post-Persist event Created: 02/Sep/10  Updated: 14/Jan/11

Status: Open
Project: Doctrine 2 - ORM
Component/s: ORM
Affects Version/s: 2.0-BETA4
Fix Version/s: None
Security Level: All

 Type: Improvement Priority: Major Reporter: arnaud-lb Assignee: Roman S. Borschel Resolution: Unresolved Votes: 0 Labels: None

 Description
 postPersist/postUpdate events are triggered in the middle of a unitOfWork, and querying the DB in such events causes infinite loops. Doctrine attempts to flush the entity manager before running any query, which triggers flushing of entities, and postPersist/postUpdate events are triggered again. I did not checked, but the flush() before each query may be a performance problem too, if doctrine has to determine what has changed, depending on the changetracking policy. Also, it would be great if postPersist / postUpdate events were triggered after all entities have been persisted. It looks like that entities are flushed by groups of same 'type', and that events for a type are triggered once all of the elements of that group have been flushed, potentially before entities of an other type have been flushed : postPersist / postUpdate events are triggered while some other entities are still not flushed.

 Comment by Benjamin Eberlei [ 03/Sep/10 ] That is documented and for perfomance reasons we cannot move the preUpdate/postUpdate/prePersist/postPersist events to other locations inside the UnitOfWork. There is an onFlush event that allows for more flexibility and is triggered before any update/insert/delete is done by the UnitOfWork. Comment by arnaud-lb [ 04/Sep/10 ] Thanks. I understand that. Is there any chance of getting some onPostFlush or similar, which would be triggered like onFlush, but after all update/insert/delete ? Or just some post-something event which is allowed to issue db queries. Comment by Gediminas Morkevicius [ 24/Sep/10 ] onFlush you can store your entity for furher processing and on postPersist you can check if there are no more insertions and process the entity if it needs additional query I have faced all these issues and you can check http://github.com/l3pp4rd/DoctrineExtensions/tree/master/lib/DoctrineExtensions/Translatable/ for a solution to your problem Comment by Gediminas Morkevicius [ 14/Jan/11 ] I think this issue should be closed since the main reason of opening it was the possibility to execute additional queries when inserts were pending in unit of work. In current release it does not cause a flush during an additional query execution anymore.

### [DDC-803] Create subselect queries within join statements Created: 14/Sep/10  Updated: 14/Sep/10

Status: Open
Project: Doctrine 2 - ORM
Component/s: None
Affects Version/s: None
Fix Version/s: None
Security Level: All

 Type: New Feature Priority: Major Reporter: Martijn Evers Assignee: Roman S. Borschel Resolution: Unresolved Votes: 0 Labels: None

### [DDC-810] Issue with detaching entities and updating when using change notification Created: 17/Sep/10  Updated: 04/Jul/11

Status: Open
Project: Doctrine 2 - ORM
Component/s: None
Affects Version/s: 2.0-BETA4
Fix Version/s: 2.x
Security Level: All

 Type: Improvement Priority: Major Reporter: Jonathan H. Wage Assignee: Roman S. Borschel Resolution: Unresolved Votes: 0 Labels: None

 Attachments: DDC810Test.php

 Description

 Comment by Benjamin Eberlei [ 20/Sep/10 ] From reading the issue i know what the bug is, indeed this sucks. Comment by Roman S. Borschel [ 28/Sep/10 ] @Jon: Any more information coming? @Benjamin: Can you summarize the essence of the issue shortly? Comment by Benjamin Eberlei [ 29/Sep/10 ] @Roman: The UnitOfWork (may) still be pushed as a listener into that entity, and still recieve noticies of update. Which may throw notices because the oid hashes are removed everywhere. Additionally you cant serialize the thing because you still got the UoW inside there. Comment by Jonathan H. Wage [ 04/Oct/10 ] I don't have anymore information currently. The issue was relayed to me. I will try and find some more information and report back. Comment by Benjamin Eberlei [ 03/Apr/11 ] There is no way to "fix" this issue, i am turning it into a feature request. There needs to be a "postDetach" event that is triggered where the developer can detach the change notification objects.

### [DDC-813] Validate Schema should complain on bi-directional relationships with mapped superclasses Created: 21/Sep/10  Updated: 29/Oct/12

Status: Open
Project: Doctrine 2 - ORM
Component/s: Tools
Affects Version/s: 2.0-BETA4
Fix Version/s: None
Security Level: All

 Type: Improvement Priority: Major Reporter: Benjamin Eberlei Assignee: Benjamin Eberlei Resolution: Unresolved Votes: 0 Labels: None

 Description
 @ManyToOne and @OneToOne on mapped superclasses have to be unidirectional. The Schema Validator should verify this.

### [DDC-851] Automerge of detached entities passed to doctrine Created: 31/Oct/10  Updated: 30/Dec/10

Status: Open
Project: Doctrine 2 - ORM
Component/s: ORM
Affects Version/s: 2.0-BETA4
Fix Version/s: None
Security Level: All

 Type: Improvement Priority: Major Reporter: Daniel Alvarez Arribas Assignee: Roman S. Borschel Resolution: Unresolved Votes: 0 Labels: None

 Description

### [DDC-1217] Use the DBAL ReservedKeywordsValidator in orm:validate-schema Created: 20/Jun/11  Updated: 20/Jun/11

Status: Open
Project: Doctrine 2 - ORM
Component/s: Tools
Affects Version/s: 2.0.6, Git Master
Fix Version/s: None
Security Level: All

 Type: Improvement Priority: Major Reporter: Christophe Coevoet Assignee: Benjamin Eberlei Resolution: Unresolved Votes: 0 Labels: None

 Description
 DBAL provides a ReservedKeywordsValidator to check whether a word is reserved. But this tool is not used by the ORM when validating the schema. It would be useful to use it to avoid WTF from users getting a PDOException when creating their schema because of this. The other solution if you don't want to add this in orm:validate-schema would be to create a dedicated command.

### [DDC-1219] Remove dependancy on Collection interface in Domain Objects Created: 21/Jun/11  Updated: 04/Jul/11

Status: Open
Project: Doctrine 2 - ORM
Component/s: ORM
Affects Version/s: 2.1
Fix Version/s: 2.x
Security Level: All

 Type: Improvement Priority: Major Reporter: André R. Assignee: Benjamin Eberlei Resolution: Unresolved Votes: 0 Labels: None

 Description

### [DDC-1393] Skipping tables or columns in database driver or SchemaTool Created: 24/Sep/11  Updated: 20/Dec/11

Status: Open
Project: Doctrine 2 - ORM
Component/s: None
Affects Version/s: 2.1.1, Git Master
Fix Version/s: 2.x
Security Level: All

 Type: Improvement Priority: Major Reporter: Benjamin Eberlei Assignee: Benjamin Eberlei Resolution: Unresolved Votes: 0 Labels: None

 Description
 There should be a sane way to skip sources of errors in SchemaTool and the DatabaseDriver.

 Comment by Benjamin Eberlei [ 24/Sep/11 ] Idea: Develop a datastructure of sorts that allows saving information about skipping tables and columns therein when reverse engeneering. Comment by Guilherme Blanco [ 09/Dec/11 ] This is not possible unless you take advantage of Topological Sorting to map class dependencies like we do inside of UnitOfWork AFTER creating the ClassMetadata. The necessity of having this is mandatory because we can never skip classes that have associations to other ones though FK. You may try that, but it doesn't compensate the effort. I'd rather mark this bug as won't fix, but I'm leaving for you do that. =) Comment by Guilherme Blanco [ 20/Dec/11 ] Updating fix version

### [DDC-1415] EventListener delegate on entity basis Created: 11/Oct/11  Updated: 20/Dec/11

Status: Reopened
Project: Doctrine 2 - ORM
Component/s: None
Affects Version/s: None
Fix Version/s: 2.x
Security Level: All

 Type: New Feature Priority: Major Reporter: Benjamin Eberlei Assignee: Benjamin Eberlei Resolution: Unresolved Votes: 0 Labels: None

 Comment by Benjamin Eberlei [ 12/Dec/11 ] Removed from master, as i dont like the api at all Comment by Guilherme Blanco [ 20/Dec/11 ] Updating fix version

### [DDC-1429] Add a method to the unit of work that merges any detached entity into UoW without calling SQL Created: 17/Oct/11  Updated: 17/Oct/11

Status: Open
Project: Doctrine 2 - ORM
Component/s: ORM
Affects Version/s: None
Fix Version/s: None
Security Level: All

 Type: Improvement Priority: Major Reporter: Benjamin Eberlei Assignee: Benjamin Eberlei Resolution: Unresolved Votes: 0 Labels: None

 Description
 This is for those that know what they are doing

### [DDC-1431] Current event system is not flexible enough Created: 18/Oct/11  Updated: 18/Oct/11

Status: Open
Project: Doctrine 2 - ORM
Component/s: ORM
Affects Version/s: 2.1
Fix Version/s: None
Security Level: All

 Type: Improvement Priority: Major Reporter: Oleg Stepura Assignee: Benjamin Eberlei Resolution: Unresolved Votes: 1 Labels: None Environment: Doctrine 2.1

 Key Summary Type Status Assignee DDC-1449 Create postFlush event Sub-task Resolved Benjamin Eberlei

 Description
 Hi! Current event system seem to be not as flexible as it could be. 1. According Lifecycle Events of the entity (marked with @HasLifecycleCallbacks annotation tag): It would be useful to have access to Entity Manager inside the callbacks. This could be achieved by passing the entity manager as a parameter to all these callbacks. Here is the situation: I have an entity for a news item. After somehow modifying this entity and before persisting I want to be able to change the inner association of images linked to this news (for example parsed from news body text). From the OO point of view it's a task of the News entity itself so this should be done a callback. But since inside callback I do not have access to entity manager (to find existing image entities and only if not found creating a new one) I cannot do this. This leads to creating a separate event listener which is split from the news entity (and that is not possible, see 2.). Passing entity manager to callbacks may improve it's usefulness. 2. Currently there is no events to be called before the changes have been computed. And there is no callback to be called after flush has been finished. (preFlush, postFlush) The problem: Assume we have a News entity. I want to modify external system (even not written in PHP) via remote call after any change to news being made. This has to be called AFTER the flush has persisted all the changes. Currently the only place to do this is onFlush (which is called before the persisting is done). PostPersist, postRemove, postUpdate cannot be used as it's called after each one entity is modified and we cannot tell when all entites has been processed. Also I faced a problem when implementing the event listener for situation 1. If I register the onFlush listener - the entites changeset is already calculated. If I change something according associations I loose this changes. If I call $unitOfWork->computeChangeSet($classMetadata, $entity) or$unitOfWork->recomputeSingleEntityChangeSet($classMetadata,$entity); I only get the changes being made after previous changeset calculation loosing the initial changes. I think the preFlush could be a lifesaver for this (to be called before computing the changeset for the first time).

### [DDC-1438] Add test for DDC-1437 Created: 19/Oct/11  Updated: 19/Oct/11

Status: Open
Project: Doctrine 2 - ORM
Component/s: None
Affects Version/s: None
Fix Version/s: None
Security Level: All

 Type: Improvement Priority: Major Reporter: Benjamin Eberlei Assignee: Benjamin Eberlei Resolution: Unresolved Votes: 0 Labels: None

 Description

### [DDC-1441] Metadata cannot be loaded for not registered proxy objects Created: 20/Oct/11  Updated: 05/Apr/12

Status: Open
Project: Doctrine 2 - ORM
Component/s: ORM
Affects Version/s: 2.1.2
Fix Version/s: None
Security Level: All

 Type: Improvement Priority: Major Reporter: Aigars Gedroics Assignee: Benjamin Eberlei Resolution: Unresolved Votes: 0 Labels: None Environment: MySQL, Ubuntu, PHP 5.3.6

 Description

### [DDC-1475] Documentation for One-To-Many, Bidirectional Association does not have YAML example Created: 07/Nov/11  Updated: 07/Nov/11

Status: Open
Project: Doctrine 2 - ORM
Component/s: Documentation
Affects Version/s: None
Fix Version/s: None
Security Level: All

 Type: Documentation Priority: Major Reporter: Christian Stoller Assignee: Benjamin Eberlei Resolution: Unresolved Votes: 0 Labels: None

 Description
 When you are looking for a config example for the bidirectional mapping of an one-to-many association you will just find an example with XML, but not with YAML or PHP. It would be nice if somebody could add an example or a link to the bidirectional one-to-one association, because it should be the same, right? Here the link to the example: http://www.doctrine-project.org/docs/orm/2.0/en/reference/association-mapping.html#one-to-many-bidirectional

Possible Regression with OneToOne relation (DDC-1461)

### [DDC-1506] Possible Regression with OneToOne relation Created: 23/Nov/11  Updated: 23/Nov/11

Status: Open
Project: Doctrine 2 - ORM
Component/s: ORM
Affects Version/s: 2.1.2
Fix Version/s: None
Security Level: All

 Type: Sub-task Priority: Major Reporter: Maxim Assignee: Benjamin Eberlei Resolution: Unresolved Votes: 0 Labels: None

 Description
 /** * @ORM\Entity */ class Top { /** * @ORM\Id * @ORM\Column(type="integer") * @ORM\GeneratedValue(strategy="AUTO") */ protected $id; /** * @ORM\OneToOne(targetEntity="LevelOne", orphanRemoval="true", cascade={"persist", "remove"}) */ protected$levelOne; public function getId() { return $this->id; } public function setLevelOne(LevelOne$levelOne) { $this->levelOne =$levelOne; } public function getLevelOne() { return $this->levelOne; } } /** * @ORM\Entity */ class LevelOne { /** * @ORM\Id * @ORM\Column(type="integer") * @ORM\GeneratedValue(strategy="AUTO") */ protected$id; /** * @ORM\OneToOne(targetEntity="LevelTwo", orphanRemoval="true", cascade={"persist", "remove"}) */ protected $levelTwo; public function getId() { return$this->id; } public function setId($id) {$this->id = $id; } public function setLevelTwo(LevelTwo$levelTwo) { $this->levelTwo =$levelTwo; } public function getLevelTwo() { return $this->levelTwo; } } /** * @ORM\Entity */ class LevelTwo { /** * @ORM\Id * @ORM\Column(type="integer") * @ORM\GeneratedValue(strategy="AUTO") */ protected$id; public function getId() { return $this->id; } public function setId($id) { $this->id =$id; } }  trying to clone objects $top = new Top();$top->setLevelOne(new LevelOne()); $top->getLevelOne()->setLevelTwo(new LevelTwo());$this->em->persist($top);$this->em->flush(); $newTop = new Top();$newTop->setLevelOne(clone $top->getLevelOne());$newTop->getLevelOne()->setId(null); $newTop->getLevelOne()->getLevelTwo()->setId(null); var_dump($newTop->getLevelOne()->getId()); var_dump($newTop->getLevelOne()->getLevelTwo()->getId());$this->em->persist($newTop);$this->em->flush();  the output is: NULL NULL [PDOException] SQLSTATE[23000]: Integrity constraint violation: 1062 Duplicate entry '1' for key 'UNIQ_82A72CD0778BC57F' (it duplicates level two entity) I worked for a while with entities, in a certain set of entity properties it completely persisted into database, but without relation between level one and level two.

### [DDC-1507] State change detection for version incrementation (for optimistic locking) in combination with orphanRemoval Created: 23/Nov/11  Updated: 27/Nov/11

Status: Open
Project: Doctrine 2 - ORM
Component/s: ORM
Affects Version/s: 2.1.4
Fix Version/s: None
Security Level: All

 Type: Improvement Priority: Major Reporter: Georg Wächter Assignee: Benjamin Eberlei Resolution: Unresolved Votes: 1 Labels: None

 Description
 As i understand the documentation correctly, orphanRemoval associations have the meaning of a "part of" relationship. In the example (http://www.doctrine-project.org/docs/orm/2.0/en/reference/working-with-associations.html#orphan-removal) the adresses are part of the contact. In my opinion we should reason that the state of the adress consists of the states of all nested contacts. As a consequence we should flag the contact as "dirty" when the adresses change. This is relevant for optimistic locking scenarios or event handlers. In my application i tried to use optimistic locking for "contacts", which does not work if i don't change anything in the contact but only in the nested addresses.

 Comment by Benjamin Eberlei [ 27/Nov/11 ] This is still only an approvement, you can workaround this and handle is in your domain code. Comment by Georg Wächter [ 27/Nov/11 ] Not in all cases. The first problem is that my domain code can't modify the version property, doctrine seems to block any manipulations to it. So i'm not able to increment the variable myself. The only solution is to implement optimistic locking on my own or to add a dummy persistent boolean field that gets inversed by my domain code .. which would trigger the doctrine implementation for the optimistic locking. I think it's clear that the second option shouldn't be a choice. If doctrine doesn't handle the overall case exactly it should allow me to increment the version number myself.

### [DDC-1513] Missing documentation for using references in Docs Created: 28/Nov/11  Updated: 29/Nov/11

Status: Open
Project: Doctrine 2 - ORM
Component/s: Documentation
Affects Version/s: None
Fix Version/s: None
Security Level: All

 Type: Documentation Priority: Major Reporter: Thomas Gray Assignee: Benjamin Eberlei Resolution: Unresolved Votes: 0 Labels: None

 Description
 I am in the process of switching over from Doctrine 2.0.7 to Doctrine 2.1 and one of the major missing components in my entities was the new use of using the mapping entity. Example: 

 Comment by Erik Bernhardson [ 28/Nov/11 ] I also glanced through the docs and didn't find it. I would suggest it be added to the Annotations Reference page: http://www.doctrine-project.org/docs/orm/2.1/en/reference/annotations-reference.html Comment by Thomas Gray [ 29/Nov/11 ] Ahh, so there are some docs about it; http://www.doctrine-project.org/docs/common/2.1/en/reference/annotations.html however they do not seem to be that clear; nor well linked too.

### [DDC-1530] HIDDEN values cannot be used in WhereClause Created: 12/Dec/11  Updated: 25/Jan/12

Status: Open
Project: Doctrine 2 - ORM
Component/s: None
Affects Version/s: Git Master
Fix Version/s: 2.x
Security Level: All

 Type: Improvement Priority: Major Reporter: Guilherme Blanco Assignee: Guilherme Blanco Resolution: Unresolved Votes: 0 Labels: None

 Description
 SELECT u, u.name AS HIDDEN n FROM User u WHERE n = ?1  Is broken. Error: SQLSTATE[42S22]: Column not found: 1054 Unknown column 'sclr16' in 'where clause  On a query like: SELECT s0_.id AS id0, s0_.a AS a1, s0_.b AS b2, s0_.c AS c3, s0_.d AS d4, s0_.e AS e5, s0_.f AS f6, s0_.g AS g7, s0_.h AS h8, s0_.i AS i9, s0_.j AS j10, s0_.k AS k11, s0_.l AS l12, s0_.m AS m13, s0_.n AS n14, s0_.o AS o15, 123456789 AS sclr16, s0_.p AS p17 FROM myEntity s0_ WHERE s0_.a = 1 AND sclr16 <= ? ORDER BY sclr16 ASC 

 Comment by Guilherme Blanco [ 20/Dec/11 ] Updating fix version Comment by Christian Raue [ 09/Jan/12 ] It occurs even if the value is not HIDDEN. Comment by Benjamin Eberlei [ 10/Jan/12 ] @Christian this sounds like a completly different error, please explain why you think this belongs here or open a new ticket. Comment by Christian Raue [ 10/Jan/12 ] Benjamin: Because I get exactly the same error message regardless of using HIDDEN. So HIDDEN doesn't seem to be liable here. Comment by Benjamin Eberlei [ 10/Jan/12 ] Can you paste your DQL and SQL? Comment by Christian Raue [ 10/Jan/12 ] Code: $queryBuilder ->select('myEntity, 123456789 AS distance') ->where('distance <= 10') ;  DQL: SELECT myEntity, 123456789 AS distance FROM MyCompany\MyBundle\Entity\MyEntity myEntity WHERE distance <= 10  SQL: SELECT s0_.id AS id0, s0_.a AS a1, s0_.b AS b2, s0_.c AS c3, s0_.d AS d4, s0_.e AS e5, s0_.f AS f6, s0_.g AS g7, s0_.h AS h8, s0_.i AS i9, s0_.j AS j10, s0_.k AS k11, s0_.l AS l12, s0_.m AS m13, s0_.n AS n14, s0_.o AS o15, 123456789 AS sclr16, s0_.p AS p17 FROM myEntity s0_ WHERE sclr16 <= 10  Comment by Benjamin Eberlei [ 11/Jan/12 ] That is expected behavior, ANSI SQL defines SELECT to be evaluated AFTER WHERE. SELECT 1234 AS foo FROM test HAVING foo = 1234  DQL has a HAVING clause as well, not sure it works without the group by. Please try. Comment by Christian Raue [ 21/Jan/12 ] So we might just close this issue then? Comment by Benjamin Eberlei [ 25/Jan/12 ] Its not a bug, just the error message is supposed to be improved (if possible) in a cheap way. ### [DDC-1532] PostFlush lifecycle event Created: 13/Dec/11 Updated: 14/Dec/11 Status: Open Project: Doctrine 2 - ORM Component/s: ORM Affects Version/s: Git Master Fix Version/s: None Security Level: All  Type: New Feature Priority: Major Reporter: Jack van Galen Assignee: Benjamin Eberlei Resolution: Unresolved Votes: 1 Labels: None  Description  In some cases, the database-id of the newly created record is needed in some postproccessing steps, like sending an e-mail containing a link to the just created entity. I've recently seen the added support for PostFlush, but this is not a lifecycle event. class SomeEntityClass{ /** @PostFlush */ function sendSomeEmail() { sendEmail(' 'Hi, you're new invoice can be found online: http://www.example.com/invoices/invoice_'.$this->id '; } } Perhaps it's even possible to have multiple PostFlush events, that differentiate between the first time a record is created, and when the record is merely updated.

 Comment by Jack van Galen [ 14/Dec/11 ] Okay, please ignore this issue, as I now see that the @PostPersist does exactly what I need. I was thrown by the name, because to me, the order in which stuff happens is persist -> flush. The ID's are only known after flush, so i'd expected something like postflush to exist. Sorry.

### [DDC-1538] GH-217: [BUG] Schema Manager had no way to define extra options Created: 14/Dec/11  Updated: 17/Dec/11

Status: Open
Project: Doctrine 2 - ORM
Component/s: None
Affects Version/s: None
Fix Version/s: None
Security Level: All

 Type: New Feature Priority: Major Reporter: Benjamin Eberlei Assignee: Benjamin Eberlei Resolution: Unresolved Votes: 0 Labels: None

 Description
 Pull-Request was automatically synchronized: https://github.com/doctrine/doctrine2/pull/217 Schema Manager had no way to define extra options ("comment" option for example). It is possible to add these options via Annotations. After the fix adding @ORM\Column(type="string", options= {"comment" = "test"} ) starts to work producing valid SQL schema with COMMENT output.

### [DDC-1543] Support for Mapping Files on Traits Created: 17/Dec/11  Updated: 17/Dec/11

Status: Open
Project: Doctrine 2 - ORM
Component/s: None
Affects Version/s: None
Fix Version/s: 2.x
Security Level: All

 Type: New Feature Priority: Major Reporter: Benjamin Eberlei Assignee: Benjamin Eberlei Resolution: Unresolved Votes: 0 Labels: None

 Description
 With PHP 5.4 and traits coming we should find a way where you can add xml and yml configurations for a trait and upon loading an entity X, it also loads the trait configuration of this entity.

### [DDC-1549] GH-232: Recursive check for entity identifiers and hashes Created: 20/Dec/11  Updated: 22/Mar/12

Status: Open
Project: Doctrine 2 - ORM
Component/s: None
Affects Version/s: None
Fix Version/s: None
Security Level: All

 Type: Improvement Priority: Major Reporter: Benjamin Eberlei Assignee: Benjamin Eberlei Resolution: Unresolved Votes: 0 Labels: None

 Description
 Pull-Request was automatically synchronized: https://github.com/doctrine/doctrine2/pull/232 Hi all! This PR will add a better support for entities with association keys. getType will check recursively to find a type for the identifier. getIndividualValue will search recursively to find the identifier value trygetById improved, using a recursive function to find an id value instead of implode functions (that cause exceptions if the identifier is an object and do not implements __toString method).

 Comment by Benjamin Eberlei [ 28/Dec/11 ] Mark as improvement Comment by Benjamin Eberlei [ 22/Mar/12 ] A related Github Pull-Request [GH-232] was https://github.com/doctrine/doctrine2/pull/232

### [DDC-1551] postFlush event listeners should be able to get a list of all flushed entities Created: 21/Dec/11  Updated: 23/May/12

Status: Open
Project: Doctrine 2 - ORM
Component/s: ORM
Affects Version/s: 2.2
Fix Version/s: None
Security Level: All

 Type: Improvement Priority: Major Reporter: Albert Casademont Assignee: Benjamin Eberlei Resolution: Unresolved Votes: 9 Labels: None

 Description
 Testing the new Doctrine 2.2 Beta we finally got the postFlush event which is a nice way to handle things after all the DB work has finished. The main problem is that there is no way to get all the flushed entities. In the onFlush event you are able to use the getScheduledEntityUpdates/Inserts/Deletions but as these entities are flushed, those arrays are now empty. To solve this i see 2 aproaches: 1. Not unseting the array that holds the scheduled entities so the getScheduledEntityUpdates/Inserts/Deletions still have data. Those arrays are reset just before finishing the commit method so maybe unsetting them one by one as they are flushed is not necessary 2. Unset the arrays but at the same time, fill another "flushedEntities" array with the flushed entities and then be able to get that array with a getFlushedEntities method I can make a patch if necessary, just wanted to know if that sounds ok before starting it

 Comment by Jasper N. Brouwer [ 23/May/12 ] I agree that Doctrine\ORM\Event\PreFlushEventArgs should contain a record of flushed entities, preferably reachable by entity-insertions/updates/deletions and collection-updates/deletions. I have a project (using Doctrine 2.1) which wrapped the flush call in my own. My flush dispatches custom preFlush/postFlush events (as they didn't exist in Doctrine 2.1), where my postFlushEventArgs does contain such a record. I've just upgraded my project to use Doctrine 2.2 and stumbled upon: Catchable fatal error: Argument 1 passed to Nw\Event\EntityEvent::postFlush() must be an instance of Nw\Event\Args\PostFlushEventArgs, instance of Doctrine\ORM\Event\PostFlushEventArgs given. It seems I've now hooked into Doctrine's postFlush (because I named the events the same way). I have renamed my events to work around this error, but I'd rather see my behavior implemented natively. PS: Using Doctrine 2.2.2 to be precise

### [DDC-1552] JTI Owning table for identifier columns could/should be the entitytable Created: 22/Dec/11  Updated: 22/Dec/11

Status: Open
Project: Doctrine 2 - ORM
Component/s: None
Affects Version/s: None
Fix Version/s: None
Security Level: All

 Type: Improvement Priority: Major Reporter: Alexander Assignee: Alexander Resolution: Unresolved Votes: 0 Labels: None

 Description
 When ordering a JTI entity on id, the generated SQL will use the table of the root entity. This is because the root entity is listed as owner of the field in the _owningTableMap, leading to non-optimal queries. More information see: https://groups.google.com/forum/#!topic/doctrine-user/znkkP7IF_Aw

 Comment by Alexander [ 22/Dec/11 ] I can pick this up if it's agreed upon that this could indeed be improved. Comment by Marco Pivetta [ 22/Dec/11 ] The problem here is that joining with a JTI causes LEFT JOINS, which don't perform very well when it comes to sorting the results. Just as a quick reference, here's where "something" should be changed to get this working: https://github.com/doctrine/doctrine2/blob/master/lib/Doctrine/ORM/Query/SqlWalker.php#L316 When the field is part of the primary key, the field used for sorting results should be the one of the table of the entity itself, and not of the root of the CTI.

### [DDC-1553] JTI Joining root tables could include ON ... AND root.id IS NOT NULL for each root in the inheritance Created: 22/Dec/11  Updated: 22/Dec/11

Status: Open
Project: Doctrine 2 - ORM
Component/s: None
Affects Version/s: None
Fix Version/s: None
Security Level: All

 Type: Improvement Priority: Major Reporter: Alexander Assignee: Alexander Resolution: Unresolved Votes: 0 Labels: None

 Description
 Would lead to more optimal queries, while still allowing for LEFT JOIN. Also related to this: https://groups.google.com/forum/#!topic/doctrine-user/znkkP7IF_Aw

 Comment by Alexander [ 22/Dec/11 ] Again I can pick this up if this improvement is agreed upon.

### [DDC-1564] MySQL Failure when using setFirstResult() and omitting setMaxResults() Created: 25/Dec/11  Updated: 28/Dec/11

Status: Open
Project: Doctrine 2 - ORM
Component/s: None
Affects Version/s: 2.1.4
Fix Version/s: None
Security Level: All

 Type: Improvement Priority: Major Reporter: Timo A. Hummel Assignee: Benjamin Eberlei Resolution: Unresolved Votes: 0 Labels: None

 Description
 When using setFirstResult() and omitting setMaxResults(), MySQL throws an error. This was very confusing for me until I dumped the SQL statements and found out the reason. I know that MySQL doesn't directly support this, their manual says that you should set the second parameter to LIMIT to a very high number (18446744073709551615 in their example). I'd recommend that either throwing an error in the specific platform driver or follow the MySQL example.

 Comment by Benjamin Eberlei [ 28/Dec/11 ] Changed into improvement, i am not sure how this relates to other databases. You can just use this workaround yourself so long.

### [DDC-1570] GH-243: Add ProxyFactoryInterface to allow custom proxy factories Created: 28/Dec/11  Updated: 23/Dec/13

Status: Open
Project: Doctrine 2 - ORM
Component/s: None
Affects Version/s: None
Fix Version/s: None
Security Level: All

 Type: Improvement Priority: Major Reporter: Benjamin Eberlei Assignee: Benjamin Eberlei Resolution: Unresolved Votes: 0 Labels: None

 Description
 Pull-Request was automatically synchronized: https://github.com/doctrine/doctrine2/pull/243 I'd love to have my custom proxy factory used with ORM, which is not possible at the moment (my experimental proxy https://github.com/juzna/doctrine2/commit/7822446036201b066e390b2e182cac1dc0c85430 and some comments about it http://blog.juzna.cz/2011/06/lazy-loading-in-php/)

 Comment by Doctrine Bot [ 23/Dec/13 ] A related Github Pull-Request [GH-243] was closed: https://github.com/doctrine/common/pull/243

### [DDC-1590] Fix Inheritance in Code-Generation Created: 09/Jan/12  Updated: 07/Sep/13

Status: Open
Project: Doctrine 2 - ORM
Component/s: None
Affects Version/s: None
Fix Version/s: 2.5
Security Level: All

 Type: Improvement Priority: Major Reporter: Benjamin Eberlei Assignee: Benjamin Eberlei Resolution: Unresolved Votes: 3 Labels: None

 Dependency is required for DDC-1579 MappedSuperClass and inheritance prob... Resolved

 Comment by Lukas Domnick [ 10/Dec/12 ] (I have no Link Privileges, but this one #DDC-1379 is a duplicate with more extent info.)

### [DDC-1599] OnFlush event in transaction Created: 14/Jan/12  Updated: 07/Sep/13

Status: Open
Project: Doctrine 2 - ORM
Component/s: ORM
Affects Version/s: Git Master
Fix Version/s: 2.5

 Type: Improvement Priority: Major Reporter: Gediminas Morkevicius Assignee: Benjamin Eberlei Resolution: Unresolved Votes: 2 Labels: None

 Description
 Is there any particular reason why onFlush event is not triggered when the transaction is allready open? https://github.com/doctrine/doctrine2/blob/master/lib/Doctrine/ORM/UnitOfWork.php#L290 It would help a lot developing listeners since this event is the mostly used one and since theres preFlush now it seems a logical solution if onFlush would be a start of transaction in general

 Comment by Benjamin Eberlei [ 14/Jan/12 ] onFluish is not the start of a transaction. It has nothing to do with this. Comment by Marco Pivetta [ 31/Mar/12 ] Is a third event needed? Or is this to be marked as "won't fix"? Comment by Benjamin Eberlei [ 31/Mar/12 ] Maybe onBeginTransaction, onCommit and onRollback. However since you can start transactions manually using $em->beginTransaction(), the Flush events are somehwat independent of transactions anyways. Comment by Gediminas Morkevicius [ 31/Mar/12 ] Well, user can start transaction anytime, but the fact is that if we think ORM we do not know nothing about the database. we just persist and flush objects. Yes I think these would be very useful, from how I see it, if you use event listeners, is: loadClassMetadata: you can apply extra mapping onFlush: you can modify entity changesets, or persist recalculate new ones, without triggering the database, since it is not used to begin the database modifications yet. onBeginTransaction: could use the database modifications keeping in sync the entity changesets. the thing about this event is that usually in behavioral way atomic updates are required. for example nestedset tree sync lft rgt columns, sortable sync the sort index, materialized path, all these requires atomic updates, and the best place is the start of transaction. onCommit: could be useful to execute right before commit, finalizing database modifications could be done. onRollback: this one is really something, since if you go far, there might be something like files uploaded during the entity processing, and you may want to remove them if transaction fails. Comment by Guilherme Blanco [ 21/May/12 ] This situation was barely documented here: http://www.doctrine-project.org/jira/browse/DDC-1443 We need a better Transaction API that completely fixes the computation of changesets and also allow more fine grained control over Entities and their corresponding information. I'd postpone this one until 3.0. ### [DDC-1602] Executors for Class Table Inheritance (JOINED) are extremely slow on MySQL Created: 15/Jan/12 Updated: 27/Jun/12 Status: Open Project: Doctrine 2 - ORM Component/s: DQL Affects Version/s: 2.2-BETA2 Fix Version/s: None Security Level: All  Type: Improvement Priority: Major Reporter: Michael Moravec Assignee: Benjamin Eberlei Resolution: Unresolved Votes: 3 Labels: None Environment: Debian, MySQL 5.5.17  Description Update and delete executors for Class Table Inheritance (JOINED) are extremely slow on MySQL platform. It is most probably due to use of subselect on the temporary table. The slowdown is really significant as the table size increases. As an example, lets have a root entity with one subclass: /** * @Entity * @InheritanceType("JOINED") * @DiscriminatorColumn(name="discr", type="string") * @DiscriminatorMap({"root" = "Root", "a" = "SubA"}) */ class Root { /** * @Column(type="integer") * @Id * @GeneratedValue */ private$id;

/**
* @Column(type="integer")
*/
private $xyz; }  /** * @Entity */ class SubA extends Root { /** * @Column(type="integer") */ private$foo;
}


Now lets perform a simple DQL UPDATE:

UPDATE Entities\Root r SET r.xyz = 123 WHERE r.id > ?


(note: always the upper half of entries)
Which creates following SQLs:

CREATE TEMPORARY TABLE Root_id_tmp (id INT NOT NULL)
INSERT INTO Root_id_tmp (id) SELECT t0.id FROM Root t0 LEFT JOIN SubA s0_ ON t0.id = s0_.id WHERE t0.id > 25000
UPDATE Root SET xyz = 123 WHERE (id) IN (SELECT id FROM Root_id_tmp)
DROP TEMPORARY TABLE Root_id_tmp


The time spent on this on MySQL 5.5.17 and PostgreSQL 9.1 is:

no. of entries 500 1000 2500 5000 10000 20000 50000
MySQL 0.26s 0.35s 1.1s 3.68s 14.13s 54.44s 338s
PostgreSQL 0.10s 0.10s 0.13s 0.15s 0.22s 0.35s 1.01s

As you can see, MySQL is drastically slower on even relatively small tables. This currently makes Doctrine unusable for this type of inheritance on MySQL. The solution probably would be to avoid subselect in WHERE clause in Doctrine\ORM\Query\Exec\MultiTableUpdateExecutor and Doctrine\ORM\Query\Exec\MultiTableDeleteExecutor.

Feel free to try/modify the test script yourself, it's here.

Comment by Benjamin Eberlei [ 15/Jan/12 ]

Its not a bug as it works. The performance drawback of JTI is discussed in the manual http://www.doctrine-project.org/docs/orm/2.1/en/reference/inheritance-mapping.html.

Changing this would be an improvement where we would hint if databases prefer subselects or joins for different operations. This would increase complexity of the SQL generation since now we are getting along with just one SQL generation strategy.

Comment by Michael Moravec [ 11/May/12 ]

Any chance to get this implemented before 2.3?

Comment by Michael Moravec [ 11/May/12 ]

I've made a change in DBAL and ORM code to implement a solution issue. It's currently more likely a proof of concept.

With the change, my results are (approximately):

no. of entries 500 1000 2500 5000 10000 20000 50000
MySQL 0.17s 0.19s 0.21s 0.26s 0.27s 0.37s 0.92s

Currently only update executor was changed.
DBAL branch with changes: https://github.com/Majkl578/doctrine-dbal/tree/DDC-1602
ORM branch with changes: https://github.com/Majkl578/doctrine2/tree/DDC-1602

Comment by Michael Moravec [ 27/Jun/12 ]

bump

### [DDC-1605] No documentation about the usage of indexes with YAML and XML Created: 16/Jan/12  Updated: 08/Apr/13

Status: In Progress
Project: Doctrine 2 - ORM
Component/s: Documentation
Affects Version/s: None
Fix Version/s: None
Security Level: All

 Type: Documentation Priority: Major Reporter: Christian Stoller Assignee: Benjamin Eberlei Resolution: Unresolved Votes: 0 Labels: documentation

 Description
 I am missing documentation about how to handle indexes in YAML and XML definition files. I had to search in the code to learn how to do that. Please add some documentation about it. This issue is related to #DDC-160 where the reporter asked for documentation about indexes in annotation mapping. EDIT: Maybe an example how I have done it with YAML would be helpful for others: User: type: entity fields: id: id: true type: integer generator: strategy: IDENTITY email: type: string length: 150 unique: true active: type: boolean indexes: indexActiveField: { name: idx_user_active, columns: [ active ] }  indexActiveField is the name of the index used by doctrine and idx_user_active is the name of the index in the database. The rest should be clear.

 Comment by Christian Stoller [ 27/Sep/12 ] Hi. I got an email notification that arbuscula has changed the status to "Awaiting Feedback". Do you need any feedback from me?

### [DDC-1621] Add support for FROM Class1 a1 JOIN Class2 a2 WITH cond queries Created: 25/Jan/12  Updated: 07/Sep/13

Status: In Progress
Project: Doctrine 2 - ORM
Component/s: None
Affects Version/s: None
Fix Version/s: 2.5
Security Level: All

 Type: New Feature Priority: Major Reporter: Benjamin Eberlei Assignee: Alexander Resolution: Unresolved Votes: 1 Labels: None

 Description
 Check feasibility of this kind of query different from FROM Class1 a1, Class2 a2 to allow arbitrary joins between classes.

 Comment by Alex [ 30/Nov/12 ] Hi all! Maybe if this task is hard, you could do a simplier variant, "FROM Class1 a1 JOIN a1,a2 WITH a2 INSTANCE OF Class2"? Doctrine 2.3 supports it, but in fact, it does not work. I can't use Class2 fields in query, and Doctrine ignores the INSTANCE OF operator when building a native queries. I am working with system where I have many inherited classes with Class Table Inheritance. When I do a JOIN query, it generates native sql query more than 1KB(?!) length, and MySQL freezes for more than 7 minutes (?!) on it. It must join only tables for Class2, but it joins all my 20 tables inherited of my base class I don't know where to send bugreport It will be very good if I could manually select a joined class to make Doctrine do a better queries. Sorry for my english, I am from Moscow.

### [DDC-1624] Locking CTI doesnt work on SQL Server Created: 29/Jan/12  Updated: 03/Oct/13

Status: Open
Project: Doctrine 2 - ORM
Component/s: ORM
Affects Version/s: 2.2
Fix Version/s: 2.5
Security Level: All

 Type: Bug Priority: Major Reporter: Benjamin Eberlei Assignee: Benjamin Eberlei Resolution: Unresolved Votes: 1 Labels: None

 Duplicate is duplicated by DBAL-559 SQL Server Platform error on LOCK MOD... Resolved

 Description
 The WITH Keyowrd is appended to the whole FROM .. JOIN .. block instead of behind the FROM block.

### [DDC-1681] loadRelated() - Method to efficiently load sets of related entities in "sub"-select strategies Created: 05/Mar/12  Updated: 06/Sep/13

Status: Open
Project: Doctrine 2 - ORM
Component/s: None
Affects Version/s: None
Fix Version/s: None
Security Level: All

 Type: New Feature Priority: Major Reporter: Benjamin Eberlei Assignee: Guilherme Blanco Resolution: Unresolved Votes: 1 Labels: None

 Description
 As per Request of Seldaek

 Comment by Jordi Boggiano [ 05/Mar/12 ] Sample: $result =$queryBuilder->select('a')->from('User', 'a')->getQuery()->getResult(); $result->loadRelated('roles'); // loads all a.roles  Would be the equivalent of: $result = $queryBuilder->select('a, r')->from('User', 'a')->join('a.roles', 'r')->getQuery()->getResult();  Except that the above does one simple query without join, then one WHERE IN query with all ids from the collection. The latter obviously does a join and retrieves everything in one - more complex - query. Bonus points if you can loadRelated multiple relations at once. Comment by Christophe Coevoet [ 05/Mar/12 ] I see an issue here: if you do a WHERE IN with the multiple ids, how do you know which entity the role is related to ? and btw, the interface you suggested above would require breaking the BC: $result is an array right now. Comment by Jordi Boggiano [ 05/Mar/12 ] The interface is just an example mimicking the way it worked in D1, take it with a grain of salt. As for the implementation, if you assume the roles table has a user_id and role column, then you can do WHERE user_id IN (1, 2, 3) and you'll get back the user ids so you know where to attach them. It might still require some joining in some cases, but the point is to keep the joins out of the main query. Comment by Guilherme Blanco [ 05/Mar/12 ] The one to be implemented would be: $result =$queryBuilder->select('a')->from('User', 'a')->getQuery()->getResult(); $em->loadRelated($result, 'roles'); // loads all a.roles  The reason for that is not all the times you have a PersistentCollection. You may have an ArrayCollection too. I just don't know yet how to handle array and ArrayCollection situations, since you may not know which class you're trying to fetch. Maybe I can try to grab the first item of array and retrieve Association information from ClassMetadata retrieved via get_class on first item. That would solve the problem. Any other ideas, feel free to give me. Comment by Vasily Khayrulin [ 06/Sep/13 ] Any news? it's really cool to use "WHERE primary_key IN " instead of joins.

### [DDC-1698] Inconsistent proxy file name & namespace result in __PHP_Incomplete_Class when unserializing entities Created: 13/Mar/12  Updated: 25/Sep/13

Status: Reopened
Project: Doctrine 2 - ORM
Component/s: ORM
Affects Version/s: 2.2, 2.2.1, 2.3, 2.4
Fix Version/s: None
Security Level: All

 Type: Improvement Priority: Major Reporter: Benjamin Morel Assignee: Marco Pivetta Resolution: Unresolved Votes: 2 Labels: proxy

 Description
 Starting with Doctrine 2.2, the Proxy classes have inconsistent naming with their file name, which raises problems with class autoloading. For example, a class named Application\Model\User creates the following proxy class: Application\Proxy\__CG__\Application\Model\User  This class is located in the following file: Application/Proxy/__CG__ApplicationModelUser.php  But whe we serialize such an entity, then unserialize it in another session, the framework autoloader expects the class to be located in: Application/Proxy/__CG__/Application/Model/User.php  But it is not. As a result, a __PHP_Incomplete_Class is created instead of the expected proxy class. I'm not sure whether this is an intended behavior, but I would assume this is a bug.

 Comment by Benjamin Morel [ 13/Mar/12 ] It looks like there is an even broader problem with the new _CG_ prefix; the PSR-0 standard for autoloading states that the underscores should be handled this way: \namespace\package\Class_Name => {...}/namespace/package/Class/Name.php  Which means that in the above example, it could even expect the file to be located in: Application/Proxy///CG///Application/Model/User.php  ... which is far away from the actual location. Upgrade to 2.2 broke this code, for us. Comment by Benjamin Eberlei [ 14/Mar/12 ] Proxy classes do not follow PSR-0. For the case unserializing objects we should provide an extra autoloader i guess. See here how symfony does it https://github.com/doctrine/DoctrineBundle/blob/master/DoctrineBundle.php#L57 Comment by Benjamin Eberlei [ 14/Mar/12 ] Comment by Benjamin Morel [ 14/Mar/12 ] Thanks for the quick fix, Benjamin. However, I have to admit that I'm not fully happy with the fix, as we (and probably many others) are not using the Doctrine autoloader. I supposed that the purpose of PSR-0 was precisely not to be tied to a particular autoloader implementation, and this benefit is lost with this version of Doctrine. You mentioned in the doc that the proxies are not PSR-0 compliant "for implementation reasons"; as this was working fine before 2.2, could you please explain what requirement prevents Doctrine from keeping the previous naming convention? Comment by Benjamin Eberlei [ 29/Mar/12 ] In 2.1 the proxies are not PSR-0 compatible themselves, however their class naming is simpler. In 2.2 we changed proxy names so that you can derive the original name of the proxy by searching for the _CG_ flag. This flag obviously contains the __ chars that some PSR autoloaders detect as directory seperators. I agree this is an unfortunate decision, but it was done this way. I do think however that we can automatically register the proxy atuoloader (if not yet done) in EntityManager#create(). This would hide this fact from developers automatically. Comment by Benjamin Morel [ 29/Oct/12 ] @Benjamin Eberlei In 2.3 we still have to manually call Autoloader::register() before unserializing entities that may contain proxies. So EntityManager::create() still doesn't register it. Is there a plan to add this feature? Comment by Benjamin Eberlei [ 06/Jan/13 ] Benjamin Morel Not at the moment, seems too dangerous for me since it might produce race conditions. This should really be done in the bootstrap of the system. We need to document this though. Comment by Benjamin Morel [ 06/Jan/13 ] Ok, thanks for your answer! Comment by Matthieu Napoli [ 09/Sep/13 ] Sorry to be a pain, but can the description of the task be updated: Affects Version/s: should show all versions (or none) but not just 2.2, 2.2.1 Fix Version/s: should be blank This is to make it clear that this bug is not resolved (since we are way past v2.2.2). Thanks Comment by Chris Hawkins [ 25/Sep/13 ] Some additional documentation about this would be useful. I just spent some considerable time diagnosing an error related to restoring an entity from a cache. I wasn't able to find a mention of the need to call Autoloader::register until I found this page. It was resolved fairly quickly after I found this. For reference, I added this to my bootstrap: ini_set('unserialize_callback_func', 'proxymissing'); function proxymissing( $name ) { if ( preg_match( '/^DoctrineProxies/',$name ) ) { \Doctrine\ORM\Proxy\Autoloader::register( PROXYPATH, 'DoctrineProxies' ); } } 

### [DDC-1702] EBNF for IN expressions should be updated for 2.2 Created: 13/Mar/12  Updated: 13/Mar/12

Status: Open
Project: Doctrine 2 - ORM
Component/s: Documentation
Affects Version/s: 2.2
Fix Version/s: None
Security Level: All

 Type: Documentation Priority: Major Reporter: Patrick Schwisow Assignee: Benjamin Eberlei Resolution: Unresolved Votes: 2 Labels: None

 Description
 Following the changes made for DDC-1472 and DDC-1416, the EBNF for InExpression should have been updated. It now takes an ArithmeticExpression instead of a SingleValuePathExpression.

 Comment by Patrick Schwisow [ 13/Mar/12 ] I marked this as "Major" because this change represents a BC break. Because EBNF was not updated, I initially believed this to be a bug in ORM and wasted a lot of time debugging Doctrine code before I discovered this change was intentional.

### [DDC-1714] Prevent inverse side lazy loading owning side of the oneToOne relationsip if owning side's id is an assosiationKey of inversed side Created: 18/Mar/12  Updated: 23/Mar/14

Status: Open
Project: Doctrine 2 - ORM
Component/s: ORM
Affects Version/s: None
Fix Version/s: None
Security Level: All

 Type: Improvement Priority: Major Reporter: David Assignee: Benjamin Eberlei Resolution: Unresolved Votes: 0 Labels: None

 Description
 This issue was originally discussed in http://www.doctrine-project.org/jira/browse/DDC-357 Say there is User and UserData with oneToOne bidirectional relationship. When we fetch User objects, UserData is lazy loaded right away. If we were to set UserData 's id as asssosiationKey of User, then user_id becomes the id of UserData and User object can already know that UserData owning side's id will equal it's own User->id. Can this be implemented?

 Comment by Doctrine Bot [ 23/Mar/14 ] A related Github Pull-Request [GH-970] was closed: https://github.com/doctrine/doctrine2/pull/970

### [DDC-1720] SqlWalter private variables should be protected to allow walker extensions Created: 21/Mar/12  Updated: 21/Mar/12

Status: Open
Project: Doctrine 2 - ORM
Component/s: ORM
Affects Version/s: 2.1.6
Fix Version/s: None
Security Level: All

 Type: Improvement Priority: Major Reporter: Ignacio Larranaga Assignee: Benjamin Eberlei Resolution: Unresolved Votes: 0 Labels: None

 Attachments: SqlWalker.patch

 Description
 I'm attaching a patch with the suggestion.

### [DDC-1721] LIKE clausule should accept functions on the pattern Created: 21/Mar/12  Updated: 01/Apr/14

Status: Awaiting Feedback
Project: Doctrine 2 - ORM
Component/s: ORM
Affects Version/s: 2.1.6
Fix Version/s: None
Security Level: All

 Type: Improvement Priority: Major Reporter: Ignacio Larranaga Assignee: Benjamin Eberlei Resolution: Unresolved Votes: 2 Labels: querybuilder,, sql-walker

 Attachments: Parser.patch     SqlWalker.patch

 Description
 Example: SELECT .... WHERE upper(n.title) LIKE upper(:filter) should be a valid SQL, now is rejected because the walker only accept a variable or an string expression. I'm adding a patch to address this.

 Comment by Ignacio Larranaga [ 21/Mar/12 ] Sorry the Parser has to be modified also to allow expressions to be recognized, I'm attaching the necessary patch. Comment by Benjamin Eberlei [ 22/Mar/12 ] I am sure there is a reason why the walker doesn't accept this such as not all supported vendors allowing functions in right hand side LIKE expressions, but i am not sure about this. Comment by Glen Ainscow [ 03/Oct/12 ] This is not possible either: WHERE CASE WHEN p.name IS NULL THEN u.username ELSE p.name END LIKE :name Comment by Thomas Mayer [ 24/Jan/13 ] In my case it worked when using "=" instead of "LIKE". //works: (CASE WHEN (Book.id = BookFrom.id) THEN BookTo.displayName ELSE BookFrom.displayName END) = :name //[Syntax Error] line 0, col 1217: Error: Expected =, <, <=, <>, >, >=, !=, got 'LIKE' (CASE WHEN (Book.id = BookFrom.id) THEN BookTo.displayName ELSE BookFrom.displayName END) LIKE :name So the LIKE operator only needs to be allowed here. I'm wondering which vendor should not be able to handle that: The CASE WHEN ... THEN ... END is documented in DQL, and allowed. LIKE itself is allowed. If an RDBMs cannot use CASE WHEN and LIKE in combination, this would be a strange limitation. Comment by Martin Keckeis [ 31/Mar/14 ] Having the same problem here. LIKE + CASE is often used in my application at the WHERE part. (e.g. data filtering of a datagrid column)

### [DDC-1723] Custom ID Generators Created: 22/Mar/12  Updated: 07/Sep/13

Status: Open
Project: Doctrine 2 - ORM
Component/s: None
Affects Version/s: None
Fix Version/s: 2.5
Security Level: All

 Type: New Feature Priority: Major Reporter: Benjamin Eberlei Assignee: Benjamin Eberlei Resolution: Unresolved Votes: 0 Labels: None

 Description
 Allow specify custom id generators, pull request is GH-206 https://github.com/doctrine/doctrine2/pull/206

### [DDC-1728] There is no exact alternative function like MONTH in mysql Created: 27/Mar/12  Updated: 27/Mar/12

Status: Open
Project: Doctrine 2 - ORM
Component/s: DQL, ORM
Affects Version/s: 2.2.0-RC1, 2.2, 2.2.1
Fix Version/s: None
Security Level: All

 Type: New Feature Priority: Major Reporter: Sudheesh MS Assignee: Benjamin Eberlei Resolution: Unresolved Votes: 0 Labels: None Environment: Ubuntu 11.10

 Description
 i am not able to extract only month from the date field using doctrine2 using 'MONTH' function

### [DDC-1729] Translate queries into graphs of value objects (instead of array hydration?) Created: 27/Mar/12  Updated: 09/Jun/12

Status: Open
Project: Doctrine 2 - ORM
Component/s: ORM
Affects Version/s: None
Fix Version/s: 2.x
Security Level: All

 Type: New Feature Priority: Major Reporter: Benjamin Eberlei Assignee: Benjamin Eberlei Resolution: Unresolved Votes: 0 Labels: None

 Description
 In decoupled applications the model layer returns "data-transfer-objects" through the boundary into the controller/view layer. It would make sense to have Doctrine directly generate any data-transfer/value-object from native and dql queries.

 Comment by Benjamin Eberlei [ 09/Jun/12 ] Example: $dql = "SELECT new CustomerAddressView(c.id, c.name, a.id, a.street, a.number, a.city, a.code) FROM Customer c INNER JOIN c.address a WHERE c.id = ?1";  This supersedes DDC-1819. 1. One additional property in ResultSetMapping =>$viewModelClass? 2. Changes to Parser (new ... syntax) 3. Changes to sQL Walker? 4. Changes to Hydration (Only object hydration!)

### [DDC-1732] Unserialized non-initialized proxy classes should throw an exception when a method is called Created: 28/Mar/12  Updated: 28/Mar/12

Status: Open
Project: Doctrine 2 - ORM
Component/s: ORM
Affects Version/s: 2.2, Git Master
Fix Version/s: None
Security Level: All

 Type: Improvement Priority: Major Reporter: Benjamin Morel Assignee: Benjamin Eberlei Resolution: Unresolved Votes: 0 Labels: None

 Attachments: ProxyFactory.php.patch

 Description
 When we serialize entities in a session, we often have pointers to uninitialized proxies. These proxies have $_entityPersister == null. The problem is that if you happen to call by mistake a method on such a proxy, you're not aware that this is an uninitialized proxy, and the business methods are called, with null values for every property. I think the proxy should throw an exception in that case. Attached, a patch with the proposed modification. ### [DDC-1738] Allow multiple Generators per class Created: 29/Mar/12 Updated: 07/Sep/13 Status: Open Project: Doctrine 2 - ORM Component/s: Mapping Drivers Affects Version/s: Git Master Fix Version/s: 2.5 Security Level: All  Type: Improvement Priority: Major Reporter: Guilherme Blanco Assignee: Benjamin Eberlei Resolution: Unresolved Votes: 0 Labels: None  Description  We should be able to support multiple generators per class. When doing partition per table, the partitioned column must be part of PK, which may enter in our limitation. Currently we only support 1 generator per class. ### [DDC-1739] [GH-314] [WIP] Doctrine\Common metadata drivers reuse Created: 30/Mar/12 Updated: 19/May/14 Status: Open Project: Doctrine 2 - ORM Component/s: None Affects Version/s: None Fix Version/s: None Security Level: All  Type: Improvement Priority: Major Reporter: Benjamin Eberlei Assignee: Benjamin Eberlei Resolution: Unresolved Votes: 0 Labels: None  Description  This issue is created automatically through a Github pull request on behalf of Ocramius: Message: This PR is strictly related with https://github.com/doctrine/common/pull/98 and tests won't pass until the doctrine-common submodule points to a merged version of it (will do so later, so please don't merge now ). Basically, I just stripped any code duplicate of what already available in dcom master under Doctrine\Common\Persistence\Mapping\Driver. Tests are OK on my environment when using the new commons submodule. (This is a cleanup for #263, where I sadly did pull from the remote branch after rebasing) Tests are still failing.  Comments  Comment by Benjamin Eberlei [ 30/Mar/12 ] A related Github Pull-Request [GH-314] was synchronize https://github.com/doctrine/doctrine2/pull/314 Comment by Benjamin Eberlei [ 30/Mar/12 ] A related Github Pull-Request [GH-314] was synchronize https://github.com/doctrine/doctrine2/pull/314 Comment by Benjamin Eberlei [ 30/Mar/12 ] A related Github Pull-Request [GH-314] was synchronize https://github.com/doctrine/doctrine2/pull/314 Comment by Benjamin Eberlei [ 30/Mar/12 ] A related Github Pull-Request [GH-314] was synchronize https://github.com/doctrine/doctrine2/pull/314 Comment by Benjamin Eberlei [ 01/Apr/12 ] A related Github Pull-Request [GH-314] was synchronize https://github.com/doctrine/doctrine2/pull/314 Comment by Benjamin Eberlei [ 04/Apr/12 ] A related Github Pull-Request [GH-314] was synchronize https://github.com/doctrine/doctrine2/pull/314 Comment by Benjamin Eberlei [ 06/Apr/12 ] A related Github Pull-Request [GH-314] was synchronize https://github.com/doctrine/doctrine2/pull/314 Comment by Benjamin Eberlei [ 07/Apr/12 ] A related Github Pull-Request [GH-314] was synchronize https://github.com/doctrine/doctrine2/pull/314 Comment by Doctrine Bot [ 19/May/14 ] A related Github Pull-Request [GH-314] was closed: https://github.com/doctrine/common/pull/314 ### [DDC-1750] [GH-319] [WIP] Added support to Multiple ID Generators Created: 01/Apr/12 Updated: 27/May/12 Status: Open Project: Doctrine 2 - ORM Component/s: None Affects Version/s: None Fix Version/s: None Security Level: All  Type: Improvement Priority: Major Reporter: Benjamin Eberlei Assignee: Benjamin Eberlei Resolution: Unresolved Votes: 0 Labels: None  Description  This issue is created automatically through a Github pull request on behalf of guilhermeblanco: Message:  Comments  Comment by Benjamin Eberlei [ 01/Apr/12 ] A related Github Pull-Request [GH-319] was synchronize https://github.com/doctrine/doctrine2/pull/319 Comment by Benjamin Eberlei [ 01/Apr/12 ] A related Github Pull-Request [GH-319] was synchronize https://github.com/doctrine/doctrine2/pull/319 Comment by Benjamin Eberlei [ 02/Apr/12 ] A related Github Pull-Request [GH-319] was synchronize https://github.com/doctrine/doctrine2/pull/319 Comment by Benjamin Eberlei [ 02/Apr/12 ] A related Github Pull-Request [GH-319] was synchronize https://github.com/doctrine/doctrine2/pull/319 Comment by Benjamin Eberlei [ 03/Apr/12 ] A related Github Pull-Request [GH-319] was synchronize https://github.com/doctrine/doctrine2/pull/319 Comment by Benjamin Eberlei [ 03/Apr/12 ] A related Github Pull-Request [GH-319] was synchronize https://github.com/doctrine/doctrine2/pull/319 Comment by Benjamin Eberlei [ 04/Apr/12 ] A related Github Pull-Request [GH-319] was synchronize https://github.com/doctrine/doctrine2/pull/319 Comment by Benjamin Eberlei [ 06/Apr/12 ] A related Github Pull-Request [GH-319] was synchronize https://github.com/doctrine/doctrine2/pull/319 Comment by Benjamin Eberlei [ 07/Apr/12 ] A related Github Pull-Request [GH-319] was synchronize https://github.com/doctrine/doctrine2/pull/319 ### [DDC-1756] Allow for master table only models on joined subclass inheritance Created: 03/Apr/12 Updated: 03/Apr/12 Status: Open Project: Doctrine 2 - ORM Component/s: ORM Affects Version/s: Git Master Fix Version/s: None Security Level: All  Type: Improvement Priority: Major Reporter: Markus Wößner Assignee: Benjamin Eberlei Resolution: Unresolved Votes: 0 Labels: None  Description  Think of a joined subclass inheritance setup where abstract base class A has many concrete child classes C1 ... CN. For each child class a table necessarily has to created. Yet if there are many child classes not defining any additional fields you will get many "id only" child tables. This leads to unnecessary join and insert overhead on database operations as well as a bunch of quite senseless tables in your schema that need to be maintained. While there are already tickets requesting support for mixed inheritance mapping (e.g. DDC-138) I want to propose another - obviously easy to implement - solution that addresses the "id only table" problem. The basic idea is to extend ClassMetadata by a flag "hasOwnTable" which is true by default and applicable for child classes of a joined subclass tree. Setting this flag to would lead to... 1.) no child table creation for corresponding model 2.) no joins to this table while rendering SQL from DQL statements 3.) no INSERT, UPDATE and DELETE statements for this table in methods executeInserts(), update() and delete() on Doctrine\ORM\Persisters\JoinedSubclassPersister. (3) can easily be implemented since the mentioned methods all loop on ClassMetadata::parentClasses. For those classes which set the flag "hasOwnTable" to false the operation will be skipped. On the other hand (2) doesn't seem to a big deal either. Extending SqlWalker::_generateClassTableInheritanceJoins() by means of a flag test seems to be enough. Of course setting the flag to while defining additional fields on child class level must be rejected. If you go for this feature I would be pleased to provide an implementation. ### [DDC-1760] [GH-324] simplified __call method Created: 03/Apr/12 Updated: 07/Apr/12 Status: Open Project: Doctrine 2 - ORM Component/s: None Affects Version/s: None Fix Version/s: None Security Level: All  Type: Improvement Priority: Major Reporter: Benjamin Eberlei Assignee: Benjamin Eberlei Resolution: Unresolved Votes: 0 Labels: None  Description  This issue is created automatically through a Github pull request on behalf of brikou: Message:  Comments  Comment by Benjamin Eberlei [ 04/Apr/12 ] A related Github Pull-Request [GH-324] was synchronize https://github.com/doctrine/doctrine2/pull/324 Comment by Benjamin Eberlei [ 06/Apr/12 ] A related Github Pull-Request [GH-324] was synchronize https://github.com/doctrine/doctrine2/pull/324 Comment by Benjamin Eberlei [ 07/Apr/12 ] A related Github Pull-Request [GH-324] was synchronize https://github.com/doctrine/doctrine2/pull/324 ### [DDC-1785] Paginator problem with SQL Server around DISTINCT keyword. Created: 18/Apr/12 Updated: 19/Jan/13 Status: Open Project: Doctrine 2 - ORM Component/s: None Affects Version/s: 2.1 Fix Version/s: None Security Level: All  Type: Bug Priority: Major Reporter: Benjamin Eberlei Assignee: Benjamin Eberlei Resolution: Unresolved Votes: 0 Labels: None  Description  PDOException: SQLSTATE[42000]: [Microsoft][SQL Server Native Client 10.0][SQL Server]Incorrect syntax near the keyword 'DISTINCT'. (uncaught exception)  Comments  Comment by Craig Mason [ 18/Oct/12 ] There are four major issues with this: 1: SQLServerPlatform.php modifies the query to prepend 'SELECT ROW_NUMBER() OVER ($over)', which is inserted before the DISTINCT keyword. 2: The order needs to be placed inside the OVER($over) block. At this point, the regex is using the exact column name rather than the alias, so the outer query cannot ORDER. 3: The DISTINCT queries select only the ID columns - as OVER() required the sort column to be available in the outer query, IDs alone will not work. 4: SQL Server cannot DISTINCT on TEXT columns. 2005,2008 and 2012 recommend using VARCHAR(MAX) instead, which does support it. That doesn't help us with 2003. We work around that with a custom TEXT type that casts as varchar. Incidentally, 2012 supports LIMIT, which gets rid of this issue altogether. Edit: Added #3 Comment by Craig Mason [ 18/Oct/12 ] I have a (very hacky) implementation working that uses regexes to correct the query so that it will execute. This also required modification in the ORM paginator, to select all columns instead of just IDs. This is certainly not a patch - more guidance. One interesting point... I had to wrap the whole query in a second SELECT *, as the WHERE IN confusingly returns non-distinct rows when part of the first inner query. No idea why this happens, but moving it out one layer makes it operate correctly. Comment by Craig Mason [ 25/Oct/12 ] Updated, view all commits for this experimental branch here: https://github.com/CraigMason/dbal/commits/mssql-distinct Comment by Craig Mason [ 29/Oct/12 ] This got waaaay too messy with regex alone due to the complicated nesting. As such, I have written the basis of a new SqlWalker class which can be used to create DISTINCT queries based on the root identifiers. It's not proper DISTINCT support, but it's a step forward. https://github.com/CraigMason/DoctrineSqlServerExtensions I've also added a Paginator (which was the original issue I had!) The current SqlWalker always sticks the ORDER BY on the end of the query, which just doesn't work properly with SqlServer. Is a vendor-specific walker breaking the DQL abstraction? Should this type of code be on the Platform object in the DBAL? Anyway, this repo fixes our immediate problem, and it would be good to revisit this in a wider context. Hopefully we can get some good SQL server support - there are plenty of other issues to deal with (UTF-8/UCS2, nvarchar etc) Comment by Benjamin Eberlei [ 19/Jan/13 ] Craig Mason We don't have an SQL Server expert on the team, so if you want really good support you should join and help us with it. ### [DDC-1803] Paginator usage with a DQL query that is using 2 time the same named binded value failed Created: 30/Apr/12 Updated: 25/Jan/13 Status: Awaiting Feedback Project: Doctrine 2 - ORM Component/s: ORM Affects Version/s: None Fix Version/s: None Security Level: All  Type: Bug Priority: Major Reporter: Marc Drolet Assignee: Benjamin Eberlei Resolution: Unresolved Votes: 0 Labels: None Environment: linux, oracle  Description  I use a dql query where I bind a named parameter 2 time in the same query for different joined fields. The query work but the count query failed saying that there are missing bind variable. ex:$qb = $this->getQueryBuilder() ->select(' partial fl. {id, title, listing_date, abstract} , partial fla. {id}, partial ca.{id} , partial ds. {id} ') ->from('Fo_Listing', 'fl') ->join('fl.listing_properties', 'flp') ->join('flp.property', 'fp') ->leftjoin('fl.listing_assets', 'fla') ->leftjoin('fla.asset', 'ca') ->leftjoin('ca.ds', 'ds') ->where('fp.id = :propertyId') ->setParameter('propertyId',$id) ->andWhere('fl.object_status_id <> :deleted') ->setParameter('deleted', CoRefObjectStatus::DELETE) ->andWhere('fl.publishing_status_id = :published') ->setParameter('published', CoRefPublishingStatus::PUBLISHED) ->andWhere('fp.object_status_id <> :deleted') ->setParameter('deleted', CoRefObjectStatus::DELETE) ->andWhere('fp.publishing_status_id = :published') ->setParameter('published', CoRefPublishingStatus::PUBLISHED) ->add('orderBy', 'fl.listing_date DESC, fl.published_date DESC') ->setMaxResults($onTheMarketLimit);$onTheMarket = new Paginator($qb,$fetchJoin = true); To make it work, I've renamed the second usage of the named variable with a 2 at the end. deleted2 and published2.

 Comment by Marco Pivetta [ 23/Jan/13 ] This seems to be quite old. Marc Drolet is it still valid with the latest ORM? Comment by Marc Drolet [ 25/Jan/13 ] I'll try to test this problem on an updated version and I'll let you know. The bug entry is also quite old and I've a local modified version of the paginator here to make it work with oracle, so it can take some time before I can test this out on the current doctrine version. Comment by Marco Pivetta [ 25/Jan/13 ] Ok, marking as awaiting feedback

### [DDC-1806] DQL with and without fetch join cause Created: 01/May/12  Updated: 01/May/12

Status: Open
Project: Doctrine 2 - ORM
Component/s: DQL, ORM
Affects Version/s: 2.2, 2.2.1, 2.2.2, Git Master
Fix Version/s: None
Security Level: All

 Type: Bug Priority: Major Reporter: Marco Pivetta Assignee: Benjamin Eberlei Resolution: Unresolved Votes: 0 Labels: None

 Attachments: DDC1806Test.php     gist2473775-d202a38fdfb91921ef010df36322fb646561593a.tar.gz

 Description
 When running following DQL in newly cleared EntityManager, with the provided entities (see attached archive or gist at https://gist.github.com/2473775 ), results in different fetched association: DQL without join: SELECT a FROM Entity\A a WHERE a.id = :id SQL without join: SELECT a0_.a_id AS a_id0, a0_.id AS id1 FROM a a0_ WHERE a0_.a_id = ? Result without join: $query->getOneOrNullResult()>getB()>getName(); // 'correct' DQL with fetch join: SELECT a, b FROM Entity\A a LEFT JOIN a.b b WHERE a.id = :id SQL with fetch join: SELECT a0_.a_id AS a_id0, b1_.id AS id1, b1_.name AS name2, a0_.id AS id3 FROM a a0_ LEFT JOIN b b1_ ON a0_.id = b1_.id WHERE a0_.a_id = ? Result with fetch join:$query->getOneOrNullResult()>getB()>getName(); // 'wrong' (different result) The problem seems to be strictly related with how the @JoinColumn` is configured.

 Comment by Marco Pivetta [ 01/May/12 ] Attaching failing test from https://github.com/Ocramius/doctrine2/compare/DDC-1806

### [DDC-1812] Modify ResultSetMapping#addMetaResult function definition Created: 06/May/12  Updated: 06/May/12

Status: Open
Project: Doctrine 2 - ORM
Component/s: None
Affects Version/s: 2.2, 2.2.1, 2.2.2, Git Master
Fix Version/s: None
Security Level: All

 Type: Improvement Priority: Major Reporter: ross neacoders Assignee: