Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Loading…

The EntityManager was not injected in uninitialized proxys which are Obj... #546

Merged
merged 3 commits into from

6 participants

@stefankleff

...ectManagerAware.

I ran into that problem while I had two objects in the identitymap while hydrating a collection: one was new a "real" entity and the other one was an uninitialized proxy. For "real" entities the em is injected in line 2427, for new entities it is injected in 2436->2364, but for proxies this is missing. According to the comment "inject ObjectManager into just loaded proxies." the code in line 2427 should do this, but in fact it is just used if it is a "real" entity or an already initialized proxy. Moving the injection to outside of the condition in line 2411 (if the entity is an unitialized proxy) solves this.

@stefankleff stefankleff The EntityManager was not injected in uninitialized proxys which are …
…ObjectManagerAware.

I ran into that problem while I had two objects in the identitymap while hydrating a collection: one was new a "real" entity and the other one was an uninitialized proxy. For "real" entities the em is injected in line 2427, for new entities it is injected in 2436->2364, but for proxies this is missing. According to the comment "inject ObjectManager into just loaded proxies." the code in line 2427 should do this, but in fact it is just used if it is a "real" entity or an already initialized proxy. Moving the injection to outside of the condition in line 2411 (if the entity is an unitialized proxy) solves this.
151192a
@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-2231

@Ocramius
Owner

@stefankleff needs a failing test to demonstrate this.

lib/Doctrine/ORM/UnitOfWork.php
((16 lines not shown))
}
}
+
+ // inject ObjectManager into just loaded proxies.
+ if ($overrideLocalValues && $entity instanceof ObjectManagerAware) {
+ $entity->injectObjectManager($this->em, $class);
+ }
@stof
stof added a note

Please use spaces, not tabs

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
lib/Doctrine/ORM/UnitOfWork.php
((16 lines not shown))
}
}
+
+ // inject ObjectManager into just loaded proxies.
+ if ($overrideLocalValues && $entity instanceof ObjectManagerAware) {
@Ocramius Owner

This will inject the EntityManager even in entities where it was (eventually) manually set.

You are right - but it was the same before!?

@Ocramius Owner

@stefankleff before, it was only handled on refresh. Now you inject it each time

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
lib/Doctrine/ORM/UnitOfWork.php
((16 lines not shown))
}
}
+
+ // inject ObjectManager into just loaded proxies.
@Ocramius Owner

Fix indentation here

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
@stefankleff stefankleff fixed indentation
Restored old way of injection to just inject it during a refresh
Added injection for initialized proxies
dc925cc
@stefankleff

I'll try to provide a test for this. Can someone please point me to a guide or something else how to run doctrine tests in general? Just running phpunit fails, as well as resolving dependencies via composer.

@stof

git submodule update --init and then using phpunit

@beberlei beberlei merged commit 6032e3e into from
@guilhermeblanco

This patch is sub-optimal.
The path could be inserted after the conditional. After the if {...} else {...}, there's already a condition that checks for overrideLocalValues. All it was required was a nested if (I can't imagine I say that! blargh!) that checks for ObjectManagerAware and assign the value.

@stefankleff

This is what I did before in stefankleff@151192a - Reverted because of #546 (diff)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Jan 10, 2013
  1. @stefankleff

    The EntityManager was not injected in uninitialized proxys which are …

    stefankleff authored
    …ObjectManagerAware.
    
    I ran into that problem while I had two objects in the identitymap while hydrating a collection: one was new a "real" entity and the other one was an uninitialized proxy. For "real" entities the em is injected in line 2427, for new entities it is injected in 2436->2364, but for proxies this is missing. According to the comment "inject ObjectManager into just loaded proxies." the code in line 2427 should do this, but in fact it is just used if it is a "real" entity or an already initialized proxy. Moving the injection to outside of the condition in line 2411 (if the entity is an unitialized proxy) solves this.
  2. @stefankleff

    fixed indentation

    stefankleff authored
    Restored old way of injection to just inject it during a refresh
    Added injection for initialized proxies
  3. @stefankleff

    Added test

    stefankleff authored
This page is out of date. Refresh to see the latest.
View
14 lib/Doctrine/ORM/UnitOfWork.php
@@ -2477,17 +2477,23 @@ public function createEntity($className, array $data, &$hints = array())
if ($entity instanceof NotifyPropertyChanged) {
$entity->addPropertyChangedListener($this);
}
+
+ // inject ObjectManager into just loaded proxies.
+ if ($overrideLocalValues && $entity instanceof ObjectManagerAware) {
+ $entity->injectObjectManager($this->em, $class);
+ }
+
} else {
$overrideLocalValues = isset($hints[Query::HINT_REFRESH]);
// If only a specific entity is set to refresh, check that it's the one
if(isset($hints[Query::HINT_REFRESH_ENTITY])) {
$overrideLocalValues = $hints[Query::HINT_REFRESH_ENTITY] === $entity;
+ }
- // inject ObjectManager into just loaded proxies.
- if ($overrideLocalValues && $entity instanceof ObjectManagerAware) {
- $entity->injectObjectManager($this->em, $class);
- }
+ // inject ObjectManager upon refresh.
+ if ($overrideLocalValues && $entity instanceof ObjectManagerAware) {
+ $entity->injectObjectManager($this->em, $class);
}
}
View
103 tests/Doctrine/Tests/ORM/Functional/Ticket/DDC2231Test.php
@@ -0,0 +1,103 @@
+<?php
+
+namespace Doctrine\Tests\ORM\Functional\Ticket;
+
+use Doctrine\Common\Persistence\Mapping\ClassMetadata;
+
+use Doctrine\Common\Persistence\ObjectManager;
+
+use Doctrine\Common\Persistence\ObjectManagerAware;
+
+require_once __DIR__ . '/../../../TestInit.php';
+
+class DDC237Test extends \Doctrine\Tests\OrmFunctionalTestCase
+{
+ protected function setUp()
+ {
+ parent::setUp();
+ $this->_schemaTool->createSchema(array(
+ $this->_em->getClassMetadata(__NAMESPACE__ . '\DDC2231EntityX'),
+ $this->_em->getClassMetadata(__NAMESPACE__ . '\DDC2231EntityY'),
+ ));
+ }
+
+ public function testInjectObjectManagerInProxyIfInitializedInUow()
+ {
+ $_x = new DDC2231EntityX;
+ $_y1 = new DDC2231EntityY;
+ $_y2 = new DDC2231EntityY;
+
+ $_x->data = 'X';
+ $_y1->data = 'Y1';
+ $_y2->data = 'Y2';
+
+ $_x->y = array($_y1, $_y2);
+ $_y1->x = $_x;
+ $_y2->x = $_x;
+
+ $this->_em->persist($_x);
+ $this->_em->persist($_y1);
+ $this->_em->persist($_y2);
+
+ $this->_em->flush();
+ $this->_em->clear();
+
+ $x = $this->_em->find(get_class($_x), $_x->id);
+ $y1ref = $this->_em->getReference(get_class($_y1), $_y1->id);
+
+ $this->assertInstanceOf('Doctrine\ORM\Proxy\Proxy', $y1ref);
+ $this->assertFalse($y1ref->__isInitialized__);
+
+ $y1 = $x->y->get(0);
+ $this->assertEquals($y1->data, $_y1->data);
+ $this->assertEquals($this->_em, $y1->om);
+
+ $y2 = $x->y->get(1);
+ $this->assertEquals($y2->data, $_y2->data);
+ $this->assertEquals($this->_em, $y2->om);
+ }
+}
+
+
+/**
+ * @Entity @Table(name="ddc2231_x")
+ */
+class DDC2231EntityX
+{
+ /**
+ * @Id @Column(type="integer") @GeneratedValue
+ */
+ public $id;
+ /**
+ * @Column(type="string")
+ */
+ public $data;
+ /**
+ * @OneToMany(targetEntity="DDC2231EntityY", mappedBy="x")
+ */
+ public $y;
+}
+
+
+/** @Entity @Table(name="ddc2231_y") */
+class DDC2231EntityY implements ObjectManagerAware
+{
+ /**
+ * @Id @Column(type="integer") @GeneratedValue
+ */
+ public $id;
+ /**
+ * @Column(type="string")
+ */
+ public $data;
+ /**
+ * @ManyToOne(targetEntity="DDC2231EntityX", inversedBy="y")
+ **/
+ public $x;
+
+ public $om;
+
+ public function injectObjectManager(ObjectManager $objectManager, ClassMetadata $classMetadata) {
+ $this->om = $objectManager;
+ }
+}
Something went wrong with that request. Please try again.