diff --git a/lib/Doctrine/ORM/Internal/Hydration/ObjectHydrator.php b/lib/Doctrine/ORM/Internal/Hydration/ObjectHydrator.php index c1bcc2591..3cedaada0 100644 --- a/lib/Doctrine/ORM/Internal/Hydration/ObjectHydrator.php +++ b/lib/Doctrine/ORM/Internal/Hydration/ObjectHydrator.php @@ -189,8 +189,8 @@ class ObjectHydrator extends AbstractHydrator $relation = $class->associationMappings[$fieldName]; $value = $class->reflFields[$fieldName]->getValue($entity); - if ($value === null) { - $value = new ArrayCollection; + if ($value === null || is_array($value)) { + $value = new ArrayCollection((array) $value); } if ( ! $value instanceof PersistentCollection) { diff --git a/lib/Doctrine/ORM/PersistentCollection.php b/lib/Doctrine/ORM/PersistentCollection.php index 98e3b91d8..83eab8cf1 100644 --- a/lib/Doctrine/ORM/PersistentCollection.php +++ b/lib/Doctrine/ORM/PersistentCollection.php @@ -101,13 +101,13 @@ final class PersistentCollection extends AbstractLazyCollection implements Selec /** * Creates a new persistent collection. * - * @param EntityManagerInterface $em The EntityManager the collection will be associated with. - * @param ClassMetadata $class The class descriptor of the entity type of this collection. - * @param Collection $coll The collection elements. + * @param EntityManagerInterface $em The EntityManager the collection will be associated with. + * @param ClassMetadata $class The class descriptor of the entity type of this collection. + * @param Collection $collection The collection elements. */ - public function __construct(EntityManagerInterface $em, $class, $coll) + public function __construct(EntityManagerInterface $em, $class, Collection $collection) { - $this->collection = $coll; + $this->collection = $collection; $this->em = $em; $this->typeClass = $class; $this->initialized = true; diff --git a/lib/Doctrine/ORM/Query/ResultSetMapping.php b/lib/Doctrine/ORM/Query/ResultSetMapping.php index 07b896695..bdd5de75e 100644 --- a/lib/Doctrine/ORM/Query/ResultSetMapping.php +++ b/lib/Doctrine/ORM/Query/ResultSetMapping.php @@ -347,7 +347,7 @@ class ResultSetMapping * @param string $class The class name of the joined entity. * @param string $alias The unique alias to use for the joined entity. * @param string $parentAlias The alias of the entity result that is the parent of this joined result. - * @param object $relation The association field that connects the parent entity result + * @param string $relation The association field that connects the parent entity result * with the joined entity result. * * @return ResultSetMapping This ResultSetMapping instance. diff --git a/tests/Doctrine/Tests/Models/Hydration/EntityWithArrayDefaultArrayValueM2M.php b/tests/Doctrine/Tests/Models/Hydration/EntityWithArrayDefaultArrayValueM2M.php new file mode 100644 index 000000000..8ba57db68 --- /dev/null +++ b/tests/Doctrine/Tests/Models/Hydration/EntityWithArrayDefaultArrayValueM2M.php @@ -0,0 +1,15 @@ +em->getClassMetadata('Doctrine\Tests\Models\Cache\Country'); $assoc = array('type' => 1); - $coll = new PersistentCollection($this->em, $mapping, null); + $coll = new PersistentCollection($this->em, $mapping, new ArrayCollection()); $persister = $this->createPersisterDefault(); $entity = new Country("Foo"); @@ -406,7 +407,7 @@ abstract class AbstractEntityPersisterTest extends OrmTestCase { $mapping = $this->em->getClassMetadata('Doctrine\Tests\Models\Cache\Country'); $assoc = array('type' => 1); - $coll = new PersistentCollection($this->em, $mapping, null); + $coll = new PersistentCollection($this->em, $mapping, new ArrayCollection()); $persister = $this->createPersisterDefault(); $entity = new Country("Foo"); diff --git a/tests/Doctrine/Tests/ORM/Hydration/ObjectHydratorTest.php b/tests/Doctrine/Tests/ORM/Hydration/ObjectHydratorTest.php index 8d2b9b226..eaa0b75b7 100644 --- a/tests/Doctrine/Tests/ORM/Hydration/ObjectHydratorTest.php +++ b/tests/Doctrine/Tests/ORM/Hydration/ObjectHydratorTest.php @@ -8,6 +8,8 @@ use Doctrine\ORM\Proxy\ProxyFactory; use Doctrine\ORM\Mapping\AssociationMapping; use Doctrine\ORM\Mapping\ClassMetadata; use Doctrine\ORM\Query; +use Doctrine\Tests\Models\Hydration\EntityWithArrayDefaultArrayValueM2M; +use Doctrine\Tests\Models\Hydration\SimpleEntity; use Doctrine\Tests\Models\CMS\CmsUser; @@ -1956,4 +1958,29 @@ class ObjectHydratorTest extends HydrationTestCase $hydrator = new \Doctrine\ORM\Internal\Hydration\ObjectHydrator($this->_em); $hydrator->hydrateAll($stmt, $rsm); } + + public function testFetchJoinCollectionValuedAssociationWithDefaultArrayValue() + { + $rsm = new ResultSetMapping; + + $rsm->addEntityResult(EntityWithArrayDefaultArrayValueM2M::CLASSNAME, 'e1', null); + $rsm->addJoinedEntityResult(SimpleEntity::CLASSNAME, 'e2', 'e1', 'collection'); + $rsm->addFieldResult('e1', 'a1__id', 'id'); + $rsm->addFieldResult('e2', 'e2__id', 'id'); + + $result = (new \Doctrine\ORM\Internal\Hydration\ObjectHydrator($this->_em)) + ->hydrateAll( + new HydratorMockStatement([[ + 'a1__id' => '1', + 'e2__id' => '1', + ]]), + $rsm + ); + + $this->assertCount(1, $result); + $this->assertInstanceOf(EntityWithArrayDefaultArrayValueM2M::CLASSNAME, $result[0]); + $this->assertInstanceOf('Doctrine\ORM\PersistentCollection', $result[0]->collection); + $this->assertCount(1, $result[0]->collection); + $this->assertInstanceOf(SimpleEntity::CLASSNAME, $result[0]->collection[0]); + } } diff --git a/tests/Doctrine/Tests/ORM/PersistentCollectionTest.php b/tests/Doctrine/Tests/ORM/PersistentCollectionTest.php index 9b9a067fc..e77f898d1 100644 --- a/tests/Doctrine/Tests/ORM/PersistentCollectionTest.php +++ b/tests/Doctrine/Tests/ORM/PersistentCollectionTest.php @@ -3,8 +3,10 @@ namespace Doctrine\Tests\ORM; use Doctrine\Common\Collections\ArrayCollection; +use Doctrine\Common\Collections\Collection; use Doctrine\ORM\PersistentCollection; use Doctrine\Tests\Mocks\ConnectionMock; +use Doctrine\Tests\Mocks\DriverMock; use Doctrine\Tests\Mocks\EntityManagerMock; use Doctrine\Tests\Models\ECommerce\ECommerceCart; use Doctrine\Tests\OrmTestCase; @@ -21,15 +23,16 @@ class PersistentCollectionTest extends OrmTestCase */ protected $collection; - private $_connectionMock; + /** + * @var \Doctrine\ORM\EntityManagerInterface + */ private $_emMock; protected function setUp() { parent::setUp(); - // SUT - $this->_connectionMock = new ConnectionMock(array(), new \Doctrine\Tests\Mocks\DriverMock()); - $this->_emMock = EntityManagerMock::create($this->_connectionMock); + + $this->_emMock = EntityManagerMock::create(new ConnectionMock([], new DriverMock())); } /**