Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Loading…

Added new query hints: HINT_NO_STORE_IDENTITY_MAP, HINT_NO_LOAD_ASSOCIATED_SUBTYPES #552

Closed
wants to merge 1 commit into from

3 participants

@Koc
  1. HINT_NO_STORE_IDENTITY_MAP usable for situations when we have article with big text fields and use partial loading for list articles. When we try load article by id from loaded list on same request we got partial entity. HINT_NO_STORE_IDENTITY_MAP allow avoid this.

  2. HINT_NO_LOAD_ASSOCIATED_SUBTYPES usable when we have entity which has one-to-one or many-to-one association to abstract entity with subtypes.

@doctrinebot
Collaborator

Hello,

thank you for positing this Pull Request. I have automatically opened an issue on our Jira Bug Tracker for you with the details of this Pull-Request. See the Link:

http://doctrine-project.org/jira/browse/DDC-2251

@beberlei
Owner

Both issues can be solved with PARTIAL queries and using the UnitOfWork API. Adding more query hints only confuses people with all the options.

@beberlei beberlei closed this
@Koc

It is too inconvenience removing entities by hand from identity map. Also i can remove already loaded entities from identity map.

do not store new entity in IM !== remove entity from IM

@Koc

@beberlei can you merge only HINT_NO_STORE_IDENTITY_MAP hint?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Jan 20, 2013
  1. @Koc
This page is out of date. Refresh to see the latest.
View
11 lib/Doctrine/ORM/Query.php
@@ -19,8 +19,6 @@
namespace Doctrine\ORM;
-use Doctrine\Common\Collections\ArrayCollection;
-
use Doctrine\DBAL\LockMode;
use Doctrine\ORM\Query\Parser;
@@ -111,6 +109,15 @@
*/
const HINT_LOCK_MODE = 'doctrine.lockMode';
+ /**
+ * @var string
+ */
+ const HINT_NO_STORE_IDENTITY_MAP = 'doctrine.doNotStoreIdentityMap';
+
+ /**
+ * @var string
+ */
+ const HINT_NO_LOAD_ASSOCIATED_SUBTYPES = 'doctrine.doNotLoadAssociatedSubtypes';
/**
* @var integer $_state The current state of this query.
View
11 lib/Doctrine/ORM/UnitOfWork.php
@@ -2442,7 +2442,9 @@ public function createEntity($className, array $data, &$hints = array())
$this->entityStates[$oid] = self::STATE_MANAGED;
$this->originalEntityData[$oid] = $data;
- $this->identityMap[$class->rootEntityName][$idHash] = $entity;
+ if (!isset($hints[Query::HINT_NO_STORE_IDENTITY_MAP])) {
+ $this->identityMap[$class->rootEntityName][$idHash] = $entity;
+ }
if ($entity instanceof NotifyPropertyChanged) {
$entity->addPropertyChangedListener($this);
@@ -2542,10 +2544,13 @@ public function createEntity($className, array $data, &$hints = array())
break;
case ($targetClass->subClasses):
+ $newValue = null;
// If it might be a subtype, it can not be lazy. There isn't even
// a way to solve this with deferred eager loading, which means putting
// an entity with subclasses at a *-to-one location is really bad! (performance-wise)
- $newValue = $this->getEntityPersister($assoc['targetEntity'])->loadOneToOneEntity($assoc, $entity, $associatedId);
+ if (!isset($hints[Query::HINT_NO_LOAD_ASSOCIATED_SUBTYPES])) {
+ $newValue = $this->getEntityPersister($assoc['targetEntity'])->loadOneToOneEntity($assoc, $entity, $associatedId);
+ }
break;
default:
@@ -2760,7 +2765,7 @@ public function getSingleIdentifierValue($entity)
return isset($values[$class->identifier[0]]) ? $values[$class->identifier[0]] : null;
}
-
+
/**
* Tries to find an entity with the given identifier in the identity map of
* this UnitOfWork.
View
6 tests/Doctrine/Tests/Models/Company/CompanyEmployee.php
@@ -29,6 +29,12 @@ class CompanyEmployee extends CompanyPerson
public $contracts;
/**
+ * @ManyToOne(targetEntity="CompanyContract")
+ * @JoinColumn(name="last_contract_id", referencedColumnName="id")
+ */
+ public $lastContract;
+
+ /**
* @OneToMany(targetEntity="CompanyFlexUltraContract", mappedBy="salesPerson", fetch="EXTRA_LAZY")
*/
public $soldContracts;
View
29 tests/Doctrine/Tests/ORM/Functional/IdentityMapTest.php
@@ -135,7 +135,7 @@ public function testSingleValuedAssociationIdentityMapBehaviorWithRefreshQuery()
// Should still be $user1
$this->assertSame($user1, $address2->user);
- $this->assertTrue($user2->address === null);
+ $this->assertNull($user2->address);
// But we want to have this external change!
// Solution 2: Alternatively, a refresh query should work
@@ -154,6 +154,32 @@ public function testSingleValuedAssociationIdentityMapBehaviorWithRefreshQuery()
$this->assertSame($user1->address, $address2);
}
+ public function testHintNoStoreIdentityMap()
+ {
+ $user = new CmsUser;
+ $user->status = 'dev';
+ $user->username = 'romanb';
+ $user->name = 'Roman B.';
+
+ $this->_em->persist($user);
+ $this->_em->flush();
+ $this->_em->clear();
+
+ $userFromDb = $this->_em
+ ->createQuery('select u from Doctrine\Tests\Models\CMS\CmsUser u WHERE u.username = :username')
+ ->setParameter('username', 'romanb')
+ ->setHint(Query::HINT_NO_STORE_IDENTITY_MAP, true)
+ ->getSingleResult();
+
+ $userFromDb2 = $this->_em
+ ->createQuery('select u from Doctrine\Tests\Models\CMS\CmsUser u WHERE u.username = :username')
+ ->setParameter('username', 'romanb')
+ ->setHint(Query::HINT_NO_STORE_IDENTITY_MAP, true)
+ ->getSingleResult();
+
+ $this->assertNotSame($userFromDb, $userFromDb2);
+ }
+
public function testCollectionValuedAssociationIdentityMapBehaviorWithRefreshQuery()
{
$user = new CmsUser;
@@ -285,4 +311,3 @@ private function subRoutine($em) {
return spl_object_hash($user);
}
}
-
View
35 tests/Doctrine/Tests/ORM/Functional/SingleTableInheritanceTest.php
@@ -386,4 +386,39 @@ public function testEagerLoadInheritanceHierachy()
$this->assertNotInstanceOf('Doctrine\ORM\Proxy\Proxy', $contract->getSalesPerson());
}
+
+ public function testHintNoLoadAssociatedSubtypes()
+ {
+ $this->loadFullFixture();
+
+ $employees = $this->_em->getRepository('Doctrine\Tests\Models\Company\CompanyEmployee')->findAll();
+
+ foreach ($employees as $employee) { /* @var $employee \Doctrine\Tests\Models\Company\CompanyEmployee */
+ foreach ($employee->contracts as $contract) {
+ if (null === $employee->lastContract || $employee->lastContract->getId() < $contract->getId()) {
+ $employee->lastContract = $contract;
+ }
+ }
+ }
+ $this->_em->flush();
+ $this->_em->clear();
+
+ $employees = $this->_em->getRepository('Doctrine\Tests\Models\Company\CompanyEmployee')->findAll();
+ foreach ($employees as $employee) { /* @var $employee \Doctrine\Tests\Models\Company\CompanyEmployee */
+ if ($employee->lastContract) {
+ $this->assertInstanceOf('Doctrine\Tests\Models\Company\CompanyContract', $employee->lastContract);
+ }
+ }
+
+ $this->_em->clear();
+
+ $employees = $this->_em
+ ->createQuery('SELECT e FROM Doctrine\Tests\Models\Company\CompanyEmployee e')
+ ->setHint(\Doctrine\ORM\Query::HINT_NO_LOAD_ASSOCIATED_SUBTYPES, true)
+ ->getResult();
+
+ foreach ($employees as $employee) { /* @var $employee \Doctrine\Tests\Models\Company\CompanyEmployee */
+ $this->assertNull($employee->lastContract);
+ }
+ }
}
View
10 tests/Doctrine/Tests/ORM/Query/SelectSqlGenerationTest.php
@@ -615,7 +615,7 @@ public function testSupportsMemberOfExpressionSelfReferencing()
$this->_em->getClassMetadata(get_class($person))->setIdentifierValues($person, array('id' => 101));
$q->setParameter('param', $person);
$this->assertEquals(
- 'SELECT c0_.id AS id0, c0_.name AS name1, c1_.title AS title2, c2_.salary AS salary3, c2_.department AS department4, c2_.startDate AS startDate5, c0_.discr AS discr6, c0_.spouse_id AS spouse_id7, c1_.car_id AS car_id8 FROM company_persons c0_ LEFT JOIN company_managers c1_ ON c0_.id = c1_.id LEFT JOIN company_employees c2_ ON c0_.id = c2_.id WHERE EXISTS (SELECT 1 FROM company_persons_friends c3_ INNER JOIN company_persons c4_ ON c3_.friend_id = c4_.id WHERE c3_.person_id = c0_.id AND c4_.id = ?)',
+ 'SELECT c0_.id AS id0, c0_.name AS name1, c1_.title AS title2, c2_.salary AS salary3, c2_.department AS department4, c2_.startDate AS startDate5, c0_.discr AS discr6, c0_.spouse_id AS spouse_id7, c1_.car_id AS car_id8, c2_.last_contract_id AS last_contract_id9 FROM company_persons c0_ LEFT JOIN company_managers c1_ ON c0_.id = c1_.id LEFT JOIN company_employees c2_ ON c0_.id = c2_.id WHERE EXISTS (SELECT 1 FROM company_persons_friends c3_ INNER JOIN company_persons c4_ ON c3_.friend_id = c4_.id WHERE c3_.person_id = c0_.id AND c4_.id = ?)',
$q->getSql()
);
}
@@ -1254,7 +1254,7 @@ public function testInheritanceTypeJoinInRootClassWithDisabledForcePartialLoad()
{
$this->assertSqlGeneration(
'SELECT p FROM Doctrine\Tests\Models\Company\CompanyPerson p',
- 'SELECT c0_.id AS id0, c0_.name AS name1, c1_.title AS title2, c2_.salary AS salary3, c2_.department AS department4, c2_.startDate AS startDate5, c0_.discr AS discr6, c0_.spouse_id AS spouse_id7, c1_.car_id AS car_id8 FROM company_persons c0_ LEFT JOIN company_managers c1_ ON c0_.id = c1_.id LEFT JOIN company_employees c2_ ON c0_.id = c2_.id',
+ 'SELECT c0_.id AS id0, c0_.name AS name1, c1_.title AS title2, c2_.salary AS salary3, c2_.department AS department4, c2_.startDate AS startDate5, c0_.discr AS discr6, c0_.spouse_id AS spouse_id7, c1_.car_id AS car_id8, c2_.last_contract_id AS last_contract_id9 FROM company_persons c0_ LEFT JOIN company_managers c1_ ON c0_.id = c1_.id LEFT JOIN company_employees c2_ ON c0_.id = c2_.id',
array(Query::HINT_FORCE_PARTIAL_LOAD => false)
);
}
@@ -1278,7 +1278,7 @@ public function testInheritanceTypeJoinInChildClassWithDisabledForcePartialLoad(
{
$this->assertSqlGeneration(
'SELECT e FROM Doctrine\Tests\Models\Company\CompanyEmployee e',
- 'SELECT c0_.id AS id0, c0_.name AS name1, c1_.salary AS salary2, c1_.department AS department3, c1_.startDate AS startDate4, c2_.title AS title5, c0_.discr AS discr6, c0_.spouse_id AS spouse_id7, c2_.car_id AS car_id8 FROM company_employees c1_ INNER JOIN company_persons c0_ ON c1_.id = c0_.id LEFT JOIN company_managers c2_ ON c1_.id = c2_.id',
+ 'SELECT c0_.id AS id0, c0_.name AS name1, c1_.salary AS salary2, c1_.department AS department3, c1_.startDate AS startDate4, c2_.title AS title5, c0_.discr AS discr6, c0_.spouse_id AS spouse_id7, c1_.last_contract_id AS last_contract_id8, c2_.car_id AS car_id9 FROM company_employees c1_ INNER JOIN company_persons c0_ ON c1_.id = c0_.id LEFT JOIN company_managers c2_ ON c1_.id = c2_.id',
array(Query::HINT_FORCE_PARTIAL_LOAD => false)
);
}
@@ -1302,7 +1302,7 @@ public function testInheritanceTypeJoinInLeafClassWithDisabledForcePartialLoad()
{
$this->assertSqlGeneration(
'SELECT m FROM Doctrine\Tests\Models\Company\CompanyManager m',
- 'SELECT c0_.id AS id0, c0_.name AS name1, c1_.salary AS salary2, c1_.department AS department3, c1_.startDate AS startDate4, c2_.title AS title5, c0_.discr AS discr6, c0_.spouse_id AS spouse_id7, c2_.car_id AS car_id8 FROM company_managers c2_ INNER JOIN company_employees c1_ ON c2_.id = c1_.id INNER JOIN company_persons c0_ ON c2_.id = c0_.id',
+ 'SELECT c0_.id AS id0, c0_.name AS name1, c1_.salary AS salary2, c1_.department AS department3, c1_.startDate AS startDate4, c2_.title AS title5, c0_.discr AS discr6, c0_.spouse_id AS spouse_id7, c1_.last_contract_id AS last_contract_id8, c2_.car_id AS car_id9 FROM company_managers c2_ INNER JOIN company_employees c1_ ON c2_.id = c1_.id INNER JOIN company_persons c0_ ON c2_.id = c0_.id',
array(Query::HINT_FORCE_PARTIAL_LOAD => false)
);
}
@@ -1398,7 +1398,7 @@ public function testSelfReferenceWithOneToOneDoesNotDuplicateAlias()
{
$this->assertSqlGeneration(
'SELECT p, pp FROM Doctrine\Tests\Models\Company\CompanyPerson p JOIN p.spouse pp',
- "SELECT c0_.id AS id0, c0_.name AS name1, c1_.title AS title2, c2_.salary AS salary3, c2_.department AS department4, c2_.startDate AS startDate5, c3_.id AS id6, c3_.name AS name7, c4_.title AS title8, c5_.salary AS salary9, c5_.department AS department10, c5_.startDate AS startDate11, c0_.discr AS discr12, c0_.spouse_id AS spouse_id13, c1_.car_id AS car_id14, c3_.discr AS discr15, c3_.spouse_id AS spouse_id16, c4_.car_id AS car_id17 FROM company_persons c0_ LEFT JOIN company_managers c1_ ON c0_.id = c1_.id LEFT JOIN company_employees c2_ ON c0_.id = c2_.id INNER JOIN company_persons c3_ ON c0_.spouse_id = c3_.id LEFT JOIN company_managers c4_ ON c3_.id = c4_.id LEFT JOIN company_employees c5_ ON c3_.id = c5_.id",
+ "SELECT c0_.id AS id0, c0_.name AS name1, c1_.title AS title2, c2_.salary AS salary3, c2_.department AS department4, c2_.startDate AS startDate5, c3_.id AS id6, c3_.name AS name7, c4_.title AS title8, c5_.salary AS salary9, c5_.department AS department10, c5_.startDate AS startDate11, c0_.discr AS discr12, c0_.spouse_id AS spouse_id13, c1_.car_id AS car_id14, c2_.last_contract_id AS last_contract_id15, c3_.discr AS discr16, c3_.spouse_id AS spouse_id17, c4_.car_id AS car_id18, c5_.last_contract_id AS last_contract_id19 FROM company_persons c0_ LEFT JOIN company_managers c1_ ON c0_.id = c1_.id LEFT JOIN company_employees c2_ ON c0_.id = c2_.id INNER JOIN company_persons c3_ ON c0_.spouse_id = c3_.id LEFT JOIN company_managers c4_ ON c3_.id = c4_.id LEFT JOIN company_employees c5_ ON c3_.id = c5_.id",
array(Query::HINT_FORCE_PARTIAL_LOAD => false)
);
}
Something went wrong with that request. Please try again.