Symfony - Неопределенный индекс чужого свойства многотонального отношения
Случай немного запутанный. У меня есть действие контроллера editCreateFirstFormPart
, которое обрабатывает некоторые поля объекта Workflow
и отображает соответствующую первую часть двухраздельной формы.
Если я вызову маршрут этого метода действия с идентификатором сохраненного объекта, форма загрузит все поля, как и должно быть. Я сохраняю объект базы данных, который заполняет форму, в текущем сеансе на случай, если пользователь решит отменить редактирование во второй форме:
// Persist all changes of made in the first form part
$manager->persist($workflow);
$manager->flush();
// In case the wolkflow already exists store it in the session
if(!$newWorkflow) $this->get('session')->set($workflowSessionName, $workflowBeforeSubmit);
return $this->redirectToRoute('pec_test_pra_edit_workflow_second_part', array(
'project' => $project->getId(),
'workflow' => $workflow->getId(),
'newWorkflow' => $newWorkflow,
// Pass the name in the session of the stored workflow to the action method which handles the second form
'workflowSessionName' => $workflowSessionName,
));
Это работает как заклинание. Теперь, в случае (который я получаю), пользователь отправляет вторую форму с помощью кнопки cancel
, я хочу сбросить объект, хранящийся в базе данных, в состояние ДО отправки первой части формы. Поэтому я извлекаю объект, сохраненный в сеансе, и хочу persist
его:
if($sessionObject instanceof Workflow) {
$manager = $this->getObjectManager();
$sessionObject = $session->get($workflowSessionName);
$manager->persist($sessionObject);
$manager->flush();
}
И здесь я получаю следующую ошибку:
Обратите внимание: Неопределенный индекс: 0000000061675b3d0000000022ddb0a6 в vendor\doctrine\orm\lib\Doctrine\ORM\UnitOfWork.php (строка 2917)
Линия 2917:return $this->entityIdentifiers[spl_object_hash($entity)];
UnitOfWork->getentityidentifier(объект(Топливо))//вызывается после prepareUpdateData
basicentitypersister->Подготовить обновленные данные(объект(mproject))
Моя сущность Workflow
имеет однонаправленное множество отношение к классу Project
. Класс MProject
расширяет Project
и имеет одно свойство класса fuel
Fuel
.
Итак, у одного Fuel
много MProject
( онетОмАния) и У многих MProject
есть один Fuel
( Многотонный). Вот соответствующие части файлов .orm.yml
:
Fuel.orm.yml
:
'ABundle\Entity\Fuel':
...
oneToMany:
projects:
targetEntity: 'ABundle\Entity\MProject'
mappedBy: fuel
Внутри Fuel
класс:
class Fuel {
/**
* The collection of projects using the fuel.
*
* @var \Doctrine\Common\Collections\Collection
*/
private $projects;
...
}
MProject.orm.yml
:
'ABundle\Entity\MProject':
repositoryClass: 'ABundle\Repository\MProjectRepository'
type: entity
manyToOne:
fuel:
targetEntity: 'ABundle\Entity\Fuel'
inversedBy: projects
Внутри MProject
класс:
use BBundle\Entity\Project as BaseProject; // Origin of Project in my Entity
class MProject extends BaseProject implements SearchableTypeAlias {
/**
* The fuel used by the project.
*
* @var Fuel
*/
protected $fuel;
...
}
Workflow.orm.yml
:
MyBundle\Entity\Workflow:
...
manyToOne:
project:
targetEntity: BBundle\Entity\Project
cascade: [persist]
...
Внутри Workflow
класс:
use BBundle\Entity\Project;
class Workflow {
/**
* @var Project
*/
private $project;
...
}
Я действительно не знаю, что не так в моем случае использования, особенно потому, что нет проблем с сохранением объекта $workflow
с вызовом persist
в первом контроллере метод действия.
Как я могу исправить эту Неопределенный индекс ошибку?
2 answers
Ваша проблема в том, что вы пытаетесь сохранить сущности , отделенные от EntityManager
. Workflow
, Project
сущности помечаются как NEW
и назначаются для вставки вместо обновления. Во время исследования ассоциации project->fuel
сеанса Project
обнаруживается другая сущность Fuel
с непустым значением id
. Но он отсоединен и id
не может быть найден в EntityManager
, поэтому возникает исключение.
Сущности, которые должны иметь соответствующую строку в БД, но загружены не EntityManager
(несериализованный из сеанса в вашем примере) должен быть объединен в EntityManager
. Вы должны объединить все Workflow
, Project
, Fuel
примеры. Самым простым способом будет настроить ассоциации workflow->project
и project->fuel
для каскадного слияния cascade: [merge]
и объединить только сеанс Workflow
.
$manager = $this->getObjectManager();
$sessionObject = $session->get($workflowSessionName);
$manager->merge($sessionObject);
$manager->flush();
Обратите внимание, что это автоматически заменит значения полей сущностей значениями, полученными из сеанса.
Поскольку вы используете перенаправление на маршрут, создается новый запрос для загрузки второй части формы. На этом этапе карта идентификаторов была перестроена и не имеет ссылки на сопоставление (длинный идентификатор) для ранее загруженного объекта сеанса (рабочего процесса). Попробуйте снова извлечь объект из базы данных и задать свойства со значениями объекта сеанса.
PS: Возможно, есть более чистый способ сделать это, о котором я не знаю.