Merge pull request #6760 from doctrine/fix/#6759-showstopper-one-to-one-inverse-not-being-loaded-with-correct-identifier-restrictions
#6759 showstopper one-to-one inverse not being loaded with correct identifier restrictions when defining `joinColumn`
This commit is contained in:
commit
f2dc9a8f92
@ -792,6 +792,8 @@ class BasicEntityPersister implements EntityPersister
|
|||||||
$sourceClass = $this->em->getClassMetadata($assoc['sourceEntity']);
|
$sourceClass = $this->em->getClassMetadata($assoc['sourceEntity']);
|
||||||
$owningAssoc = $targetClass->getAssociationMapping($assoc['mappedBy']);
|
$owningAssoc = $targetClass->getAssociationMapping($assoc['mappedBy']);
|
||||||
|
|
||||||
|
$computedIdentifier = [];
|
||||||
|
|
||||||
// TRICKY: since the association is specular source and target are flipped
|
// TRICKY: since the association is specular source and target are flipped
|
||||||
foreach ($owningAssoc['targetToSourceKeyColumns'] as $sourceKeyColumn => $targetKeyColumn) {
|
foreach ($owningAssoc['targetToSourceKeyColumns'] as $sourceKeyColumn => $targetKeyColumn) {
|
||||||
if ( ! isset($sourceClass->fieldNames[$sourceKeyColumn])) {
|
if ( ! isset($sourceClass->fieldNames[$sourceKeyColumn])) {
|
||||||
@ -800,15 +802,11 @@ class BasicEntityPersister implements EntityPersister
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// unset the old value and set the new sql aliased value here. By definition
|
$computedIdentifier[$targetClass->getFieldForColumn($targetKeyColumn)] =
|
||||||
// unset($identifier[$targetKeyColumn] works here with how UnitOfWork::createEntity() calls this method.
|
|
||||||
$identifier[$targetClass->getFieldForColumn($targetKeyColumn)] =
|
|
||||||
$sourceClass->reflFields[$sourceClass->fieldNames[$sourceKeyColumn]]->getValue($sourceEntity);
|
$sourceClass->reflFields[$sourceClass->fieldNames[$sourceKeyColumn]]->getValue($sourceEntity);
|
||||||
|
|
||||||
unset($identifier[$targetKeyColumn]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$targetEntity = $this->load($identifier, null, $assoc);
|
$targetEntity = $this->load($computedIdentifier, null, $assoc);
|
||||||
|
|
||||||
if ($targetEntity !== null) {
|
if ($targetEntity !== null) {
|
||||||
$targetClass->setFieldValue($targetEntity, $assoc['mappedBy'], $sourceEntity);
|
$targetClass->setFieldValue($targetEntity, $assoc['mappedBy'], $sourceEntity);
|
||||||
|
@ -0,0 +1,26 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Doctrine\Tests\Models\OneToOneInverseSideLoad;
|
||||||
|
|
||||||
|
use Doctrine\ORM\Mapping as ORM;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Entity()
|
||||||
|
* @Table(name="one_to_one_inverse_side_load_inverse")
|
||||||
|
*/
|
||||||
|
class InverseSide
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @Id()
|
||||||
|
* @Column(type="string")
|
||||||
|
* @GeneratedValue(strategy="NONE")
|
||||||
|
*/
|
||||||
|
public $id;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @OneToOne(targetEntity=OwningSide::class, mappedBy="inverse")
|
||||||
|
*/
|
||||||
|
public $owning;
|
||||||
|
}
|
@ -0,0 +1,29 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Doctrine\Tests\Models\OneToOneInverseSideLoad;
|
||||||
|
|
||||||
|
use Doctrine\ORM\Mapping as ORM;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Entity()
|
||||||
|
* @Table(name="one_to_one_inverse_side_load_owning")
|
||||||
|
*/
|
||||||
|
class OwningSide
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @Id()
|
||||||
|
* @Column(type="string")
|
||||||
|
* @GeneratedValue(strategy="NONE")
|
||||||
|
*/
|
||||||
|
public $id;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Owning side
|
||||||
|
*
|
||||||
|
* @OneToOne(targetEntity=InverseSide::class, inversedBy="owning")
|
||||||
|
* @JoinColumn(nullable=false, name="inverse")
|
||||||
|
*/
|
||||||
|
public $inverse;
|
||||||
|
}
|
@ -0,0 +1,70 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Doctrine\Tests\ORM\Functional;
|
||||||
|
|
||||||
|
use Doctrine\ORM\Tools\ToolsException;
|
||||||
|
use Doctrine\Tests\Models\OneToOneInverseSideLoad\InverseSide;
|
||||||
|
use Doctrine\Tests\Models\OneToOneInverseSideLoad\OwningSide;
|
||||||
|
use Doctrine\Tests\OrmFunctionalTestCase;
|
||||||
|
|
||||||
|
class OneToOneInverseSideLoadAfterDqlQueryTest extends OrmFunctionalTestCase
|
||||||
|
{
|
||||||
|
protected function setUp()
|
||||||
|
{
|
||||||
|
parent::setUp();
|
||||||
|
|
||||||
|
try {
|
||||||
|
$this->_schemaTool->createSchema([
|
||||||
|
$this->_em->getClassMetadata(OwningSide::class),
|
||||||
|
$this->_em->getClassMetadata(InverseSide::class),
|
||||||
|
]);
|
||||||
|
} catch(ToolsException $e) {
|
||||||
|
// ignored
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @group 6759
|
||||||
|
*/
|
||||||
|
public function testInverseSideOneToOneLoadedAfterDqlQuery(): void
|
||||||
|
{
|
||||||
|
$owner = new OwningSide();
|
||||||
|
$inverse = new InverseSide();
|
||||||
|
|
||||||
|
$owner->id = 'owner';
|
||||||
|
$inverse->id = 'inverse';
|
||||||
|
$owner->inverse = $inverse;
|
||||||
|
$inverse->owning = $owner;
|
||||||
|
|
||||||
|
$this->_em->persist($owner);
|
||||||
|
$this->_em->persist($inverse);
|
||||||
|
$this->_em->flush();
|
||||||
|
$this->_em->clear();
|
||||||
|
|
||||||
|
/* @var $fetchedInverse InverseSide */
|
||||||
|
$fetchedInverse = $this
|
||||||
|
->_em
|
||||||
|
->createQueryBuilder()
|
||||||
|
->select('inverse')
|
||||||
|
->from(InverseSide::class, 'inverse')
|
||||||
|
->andWhere('inverse.id = :id')
|
||||||
|
->setParameter('id', 'inverse')
|
||||||
|
->getQuery()
|
||||||
|
->getSingleResult();
|
||||||
|
|
||||||
|
self::assertInstanceOf(InverseSide::class, $fetchedInverse);
|
||||||
|
self::assertInstanceOf(OwningSide::class, $fetchedInverse->owning);
|
||||||
|
|
||||||
|
$this->assertSQLEquals(
|
||||||
|
'select o0_.id as id_0 from one_to_one_inverse_side_load_inverse o0_ where o0_.id = ?',
|
||||||
|
$this->_sqlLoggerStack->queries[$this->_sqlLoggerStack->currentQuery - 1]['sql']
|
||||||
|
);
|
||||||
|
|
||||||
|
$this->assertSQLEquals(
|
||||||
|
'select t0.id as id_1, t0.inverse as inverse_2 from one_to_one_inverse_side_load_owning t0 WHERE t0.inverse = ?',
|
||||||
|
$this->_sqlLoggerStack->queries[$this->_sqlLoggerStack->currentQuery]['sql']
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user