Merge branch 'hotfix/#1176-merging-entities-with-composite-association-identifier'
Close #1176
This commit is contained in:
commit
b889e18a9a
@ -40,8 +40,7 @@ class AssignedGenerator extends AbstractIdGenerator
|
||||
*
|
||||
* @throws \Doctrine\ORM\ORMException
|
||||
*/
|
||||
public function generate(
|
||||
EntityManager $em, $entity)
|
||||
public function generate(EntityManager $em, $entity)
|
||||
{
|
||||
$class = $em->getClassMetadata(get_class($entity));
|
||||
$idFields = $class->getIdentifierFieldNames();
|
||||
@ -55,12 +54,8 @@ class AssignedGenerator extends AbstractIdGenerator
|
||||
}
|
||||
|
||||
if (isset($class->associationMappings[$idField])) {
|
||||
if ( ! $em->getUnitOfWork()->isInIdentityMap($value)) {
|
||||
throw ORMException::entityMissingForeignAssignedId($entity, $value);
|
||||
}
|
||||
|
||||
// NOTE: Single Columns as associated identifiers only allowed - this constraint it is enforced.
|
||||
$value = current($em->getUnitOfWork()->getEntityIdentifier($value));
|
||||
$value = $em->getUnitOfWork()->getSingleIdentifierValue($value);
|
||||
}
|
||||
|
||||
$identifier[$idField] = $value;
|
||||
|
@ -36,22 +36,22 @@ final class IdentifierFlattener
|
||||
/**
|
||||
* The UnitOfWork used to coordinate object-level transactions.
|
||||
*
|
||||
* @var \Doctrine\ORM\UnitOfWork
|
||||
* @var UnitOfWork
|
||||
*/
|
||||
private $unitOfWork;
|
||||
|
||||
/**
|
||||
* The metadata factory, used to retrieve the ORM metadata of entity classes.
|
||||
*
|
||||
* @var \Doctrine\Common\Persistence\Mapping\ClassMetadataFactory
|
||||
* @var ClassMetadataFactory
|
||||
*/
|
||||
private $metadataFactory;
|
||||
|
||||
/**
|
||||
* Initializes a new IdentifierFlattener instance, bound to the given EntityManager.
|
||||
*
|
||||
* @param \Doctrine\ORM\UnitOfWork $unitOfWork
|
||||
* @param \Doctrine\Common\Persistence\Mapping\ClassMetadataFactory $metadataFactory
|
||||
* @param UnitOfWork $unitOfWork
|
||||
* @param ClassMetadataFactory $metadataFactory
|
||||
*/
|
||||
public function __construct(UnitOfWork $unitOfWork, ClassMetadataFactory $metadataFactory)
|
||||
{
|
||||
@ -62,8 +62,9 @@ final class IdentifierFlattener
|
||||
/**
|
||||
* convert foreign identifiers into scalar foreign key values to avoid object to string conversion failures.
|
||||
*
|
||||
* @param \Doctrine\ORM\Mapping\ClassMetadata $class
|
||||
* @param array $id
|
||||
* @param ClassMetadata $class
|
||||
* @param array $id
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function flattenIdentifier(ClassMetadata $class, array $id)
|
||||
@ -72,11 +73,14 @@ final class IdentifierFlattener
|
||||
|
||||
foreach ($id as $idField => $idValue) {
|
||||
if (isset($class->associationMappings[$idField]) && is_object($idValue)) {
|
||||
/* @var $targetClassMetadata ClassMetadata */
|
||||
$targetClassMetadata = $this->metadataFactory->getMetadataFor(
|
||||
$class->associationMappings[$idField]['targetEntity']
|
||||
);
|
||||
|
||||
$associatedId = $this->unitOfWork->getEntityIdentifier($idValue);
|
||||
$associatedId = $this->unitOfWork->isInIdentityMap($idValue)
|
||||
? $this->unitOfWork->getEntityIdentifier($idValue)
|
||||
: $targetClassMetadata->getIdentifierValues($idValue);
|
||||
|
||||
$flatId[$idField] = $associatedId[$targetClassMetadata->identifier[0]];
|
||||
} else {
|
||||
|
@ -0,0 +1,23 @@
|
||||
<?php
|
||||
|
||||
namespace Doctrine\Tests\Models\MixedToOneIdentity;
|
||||
|
||||
/** @Entity */
|
||||
class CompositeToOneKeyState
|
||||
{
|
||||
const CLASSNAME = __CLASS__;
|
||||
|
||||
/**
|
||||
* @Id
|
||||
* @Column(type="string")
|
||||
* @GeneratedValue(strategy="NONE")
|
||||
*/
|
||||
public $state;
|
||||
|
||||
/**
|
||||
* @Id
|
||||
* @ManyToOne(targetEntity="Country", cascade={"MERGE"})
|
||||
* @JoinColumn(referencedColumnName="country")
|
||||
*/
|
||||
public $country;
|
||||
}
|
12
tests/Doctrine/Tests/Models/MixedToOneIdentity/Country.php
Normal file
12
tests/Doctrine/Tests/Models/MixedToOneIdentity/Country.php
Normal file
@ -0,0 +1,12 @@
|
||||
<?php
|
||||
|
||||
namespace Doctrine\Tests\Models\MixedToOneIdentity;
|
||||
|
||||
/** @Entity */
|
||||
class Country
|
||||
{
|
||||
const CLASSNAME = __CLASS__;
|
||||
|
||||
/** @Id @Column(type="string") @GeneratedValue(strategy="NONE") */
|
||||
public $country;
|
||||
}
|
@ -0,0 +1,44 @@
|
||||
<?php
|
||||
|
||||
namespace Doctrine\Tests\ORM\Functional;
|
||||
|
||||
use Doctrine\Tests\Models\MixedToOneIdentity\CompositeToOneKeyState;
|
||||
use Doctrine\Tests\Models\MixedToOneIdentity\Country;
|
||||
|
||||
class MergeCompositeToOneKeyTest extends \Doctrine\Tests\OrmFunctionalTestCase
|
||||
{
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
protected function setUp()
|
||||
{
|
||||
parent::setUp();
|
||||
|
||||
$this->_schemaTool->createSchema(array(
|
||||
$this->_em->getClassMetadata(Country::CLASSNAME),
|
||||
$this->_em->getClassMetadata(CompositeToOneKeyState::CLASSNAME),
|
||||
));
|
||||
}
|
||||
|
||||
/**
|
||||
* @group DDC-3378
|
||||
* @group 1176
|
||||
*/
|
||||
public function testMergingOfEntityWithCompositeIdentifierContainingToOneAssociation()
|
||||
{
|
||||
$country = new Country();
|
||||
$country->country = 'US';
|
||||
|
||||
$state = new CompositeToOneKeyState();
|
||||
$state->state = 'CA';
|
||||
$state->country = $country;
|
||||
|
||||
/* @var $merged CompositeToOneKeyState */
|
||||
$merged = $this->_em->merge($state);
|
||||
|
||||
$this->assertInstanceOf(CompositeToOneKeyState::CLASSNAME, $state);
|
||||
$this->assertNotSame($state, $merged);
|
||||
$this->assertInstanceOf(Country::CLASSNAME, $merged->country);
|
||||
$this->assertNotSame($country, $merged->country);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user