Fix handling entities with post generated IDs as FK
This prevents a throw in UnitOfWork#addToIdentityMap because some fields are null.
This commit is contained in:
parent
23f4f03575
commit
35c3669ebc
@ -940,7 +940,11 @@ class UnitOfWork implements PropertyChangedListener
|
|||||||
$class->setIdentifierValues($entity, $idValue);
|
$class->setIdentifierValues($entity, $idValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->entityIdentifiers[$oid] = $idValue;
|
// Some identifiers may be foreign keys to new entities.
|
||||||
|
// In this case, we don't have the value yet and should treat it as if we have a post-insert generator
|
||||||
|
if (! $this->hasMissingIdsWhichAreForeignKeys($class, $idValue)) {
|
||||||
|
$this->entityIdentifiers[$oid] = $idValue;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->entityStates[$oid] = self::STATE_MANAGED;
|
$this->entityStates[$oid] = self::STATE_MANAGED;
|
||||||
@ -948,6 +952,20 @@ class UnitOfWork implements PropertyChangedListener
|
|||||||
$this->scheduleForInsert($entity);
|
$this->scheduleForInsert($entity);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param mixed[] $idValue
|
||||||
|
*/
|
||||||
|
private function hasMissingIdsWhichAreForeignKeys(ClassMetadata $class, array $idValue) : bool
|
||||||
|
{
|
||||||
|
foreach ($idValue as $idField => $idFieldValue) {
|
||||||
|
if ($idFieldValue === null && isset($class->associationMappings[$idField])) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* INTERNAL:
|
* INTERNAL:
|
||||||
* Computes the changeset of an individual entity, independently of the
|
* Computes the changeset of an individual entity, independently of the
|
||||||
@ -1033,12 +1051,16 @@ class UnitOfWork implements PropertyChangedListener
|
|||||||
$persister = $this->getEntityPersister($className);
|
$persister = $this->getEntityPersister($className);
|
||||||
$invoke = $this->listenersInvoker->getSubscribedSystems($class, Events::postPersist);
|
$invoke = $this->listenersInvoker->getSubscribedSystems($class, Events::postPersist);
|
||||||
|
|
||||||
|
$insertionsForClass = [];
|
||||||
|
|
||||||
foreach ($this->entityInsertions as $oid => $entity) {
|
foreach ($this->entityInsertions as $oid => $entity) {
|
||||||
|
|
||||||
if ($this->em->getClassMetadata(get_class($entity))->name !== $className) {
|
if ($this->em->getClassMetadata(get_class($entity))->name !== $className) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$insertionsForClass[$oid] = $entity;
|
||||||
|
|
||||||
$persister->addInsert($entity);
|
$persister->addInsert($entity);
|
||||||
|
|
||||||
unset($this->entityInsertions[$oid]);
|
unset($this->entityInsertions[$oid]);
|
||||||
@ -1067,6 +1089,14 @@ class UnitOfWork implements PropertyChangedListener
|
|||||||
|
|
||||||
$this->addToIdentityMap($entity);
|
$this->addToIdentityMap($entity);
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
foreach ($insertionsForClass as $oid => $entity) {
|
||||||
|
if (! isset($this->entityIdentifiers[$oid])) {
|
||||||
|
//entity was not added to identity map because some identifiers are foreign keys to new entities.
|
||||||
|
//add it now
|
||||||
|
$this->addToEntityIdentifiersAndEntityMap($class, $oid, $entity);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach ($entities as $entity) {
|
foreach ($entities as $entity) {
|
||||||
@ -1074,6 +1104,30 @@ class UnitOfWork implements PropertyChangedListener
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param object $entity
|
||||||
|
*/
|
||||||
|
private function addToEntityIdentifiersAndEntityMap(ClassMetadata $class, string $oid, $entity): void
|
||||||
|
{
|
||||||
|
$identifier = [];
|
||||||
|
|
||||||
|
foreach ($class->getIdentifierFieldNames() as $idField) {
|
||||||
|
$value = $class->getFieldValue($entity, $idField);
|
||||||
|
|
||||||
|
if (isset($class->associationMappings[$idField])) {
|
||||||
|
// NOTE: Single Columns as associated identifiers only allowed - this constraint it is enforced.
|
||||||
|
$value = $this->getSingleIdentifierValue($value);
|
||||||
|
}
|
||||||
|
|
||||||
|
$identifier[$idField] = $this->originalEntityData[$oid][$idField] = $value;
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->entityStates[$oid] = self::STATE_MANAGED;
|
||||||
|
$this->entityIdentifiers[$oid] = $identifier;
|
||||||
|
|
||||||
|
$this->addToIdentityMap($entity);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Executes all entity updates for entities of the specified type.
|
* Executes all entity updates for entities of the specified type.
|
||||||
*
|
*
|
||||||
|
Loading…
x
Reference in New Issue
Block a user