Я подозреваю, что это простая проблема с объектами, не обновляющимися в памяти.
Вот мои функции репозитория:
public function insertTask($information)
{
...
$entityManager = $this->getEntityManager();
$entityManager->persist($taskObj);
$entityManager->flush();
// Update the task defects for this task
$this->updateTaskDefectTaskIds($taskObj->getId(), $task['defects']);
return $taskObj;
}
private function updateTaskDefectTaskIds($task, $defects)
{
$taskDefectIds = array();
foreach ($defects as $defect)
{
$taskDefectIds[] = intval($defect['taskDefectId']);
}
// Update the task IDs on the task defects
$this->getEntityManager()
->createQuery('UPDATE Model:TaskDefect td SET td.task = :task WHERE td.id IN (:taskDefectIds)')
->setParameter('task', $task)
->setParameter('taskDefectIds', $taskDefectIds)
->execute();
$this->getEntityManager()->flush();
}
Кажется, это работает. В основном у меня есть: - Таблица задач - Таблица TaskDefect
TaskDefects в силу того, как приложение написано, вставлять его перед выполнением задачи. Но это означает, что мне нужно, как только задача в конечном итоге будет добавлена, обновите записи TaskDefect, чтобы указать на новый TaskId.
Проблема, с которой я сталкиваюсь, - это где-то в памяти (с фактической стороны базы данных, которую она обновляет правильно), она не поднимает мои изменения. Например, я обновляю некоторые TaskDefects, чтобы указать на новый TaskId, но затем я обращаюсь к объекту Task, и он говорит, что дефектов нет.
Если я перейду на другую страницу и попытаюсь получить доступ к одной и той же задаче, то она говорит, что есть недостатки.
Поэтому я чувствую, что мне не хватает flush()
или persist()
или что-то, что останавливает сущности в памяти от обновления. Очевидно, перезагрузка страницы заставляет обновить, и тогда она отлично работает.
Вот что я имею в своем контроллере:
$task = $repository->insertTask($content); // i figured maybe at this point it too much to expect the task obj to magically update
$updatedTask = $repository->findOneById($task->getId()); // so I grab it again... but no luck
var_dump($updatedTask->getDefects()); // ... because this returns no defects
Любые идеи приветствуются. Благодарю.
Эта строка в insertTask:
return $taskObj;
Не имеет никакого отношения к тому, что происходит в updateTaskDefectTaskIds, потому что вы вообще не изменяете $ taskObj, вы просто передаете значение id, а затем обновляете объекты дефектов через DQL.
Если вы хотите, чтобы $ taskObj отражал ваши дефектные дополнения из insertTask, вы сделали бы что-то вроде этого:
public function insertTask($information)
{
...
$entityManager = $this->getEntityManager();
$entityManager->persist($taskObj);
$entityManager->flush();
// Update the task defects for this task
$this->updateTaskDefectTaskIds($taskObj, $task['defects']);
return $taskObj;
}
private function updateTaskDefectTaskIds($taskObj, $defects)
{
foreach ($defects as $defect)
{
$defect = $this->getEntityManager()->getRepository('YourBundle:Defect')->find(intval($defect['taskDefectId']));
if ($defect instanceof Defect) {
$defect->setTaskObj($taskObj);
$this->getEntityManager()->persist($defect);
$taskObj->addDefect($defect);
}
}
$this->getEntityManager()->persist($taskObj);
$this->getEntityManager()->flush();
}
Или, если вы не возражаете против дополнительного вызова db, просто обновите $ taskObj в insertTask следующим образом:
$this->getEntityManager()->refresh($taskObj);
return $taskObj;
Кроме того, доктрина любит кэшировать то, что у вас есть в памяти, поэтому, если у нее нет причин проверять db (в примере кода он не может знать о ваших изменениях), то он просто счастливо будет обслуживать вас по устаревшему объекту когда вы извлекаете объект по id.
$this->getEntityManager()->refresh($taskObj);
было все, что нужно, чтобы это исправить. Ура!