#php #symfony #doctrine #one-to-many
#php #symfony #доктрина #один ко многим
Вопрос:
У меня есть объект проблемы, и он может содержать несколько заметок, объект проблемы выглядит примерно так:
/**
* @ORMOneToMany(targetEntity="Note", mappedBy="issue", cascade={"persist"})
*/
protected $notes;
public function __construct(){
$this->notes = new ArrayCollection();
}
public function getMostRecentNote(){
$count = count($this->notes);
if($count){
return $this->notes[$count-1];
}
return "No notes";
}
public function getNotes(){
return $this->notes;
}
public function addNote(Note $note){
$this->notes[] = $note;
}
//add an auto not when status changes
public function setStatus($status){
if($status === $this->status){
return;
}
$note = new Note();
$note->setNote_date(new DateTime());
$note->setNote("Status changed from "
.$this->status
." to ".$status);
$note->setIssue($this);
$this->addNote($note);
$this->status=$status;
}
Примечание выглядит следующим образом:
/**
* @var integer $id
*
* @ORMColumn(name="id", type="integer")
* @ORMId
* @ORMGeneratedValue(strategy="AUTO")
*
*/
protected $id;
/**
* @ORMManyToOne(targetEntity="Issue", inversedBy="notes", cascade={"persist"})
* @ORMJoinColumn(name="issue_id", referencedColumnName="id")
**/
protected $issue;
Когда я меняю статус, я получаю следующую ошибку:
При выполнении ‘ВСТАВИТЬ В ЗНАЧЕНИЯ issue_notes (issue_id, примечание, note_date) (?, ?, ?)’ с параметрами {«1″: null,»2″:»Статус изменен с сообщенного на в процессе»,»3″:»2014-06-20 11:14:43″}:
SQLSTATE[23000]: нарушение ограничения целостности: столбец 1048 ‘issue_id’ не может быть нулевым
Я нашел несколько вопросов по этому поводу, касающихся взаимно однозначных отношений, но, насколько я вижу, имена столбцов правильные, и есть inverseby, а также mappedby .
[решаемая]
Проблема была в получателях и установщиках заметок для выпуска:
public function getIssue()
{
return $this->issue;
}
public function setIssue($issue)
{
$this->issue=$issue;
}
установщик был $this->issues
, изменил его на код, как указано выше. Конечно, поскольку Note является стороной-владельцем и определяет обновление, я должен установить проблему для примечания: $note->setIssue($this);
(добавлена строка в коде выше). Теперь, если я создаю новую проблему, мне не нужно явно устанавливать ussue_id примечания (я еще не знаю его, прежде чем продолжать). Еще не пробовал создавать новую проблему с примечанием, но уверен, что это сработает.
[обновление]
Почти сразу же возникла следующая ошибка [Semantical Error] ... Doctrine Class Note has no association named issue_id
. Я предположил, что, установив связь между Note и Issue doctrine, можно было бы определить эту заметку как поле с именем issue_id, но это не так. Пришлось добавить следующее к сведению:
/**
* @var integer $issue_id
*
* @ORMColumn(name="issue_id", type="integer")
*
*/
protected $issue_id;
Теперь я могу запустить dql, например: SELECT n FROM AcmeDemoBundle:Note n n.issue_id = ?
Ответ №1:
Я не рассматривал метод add() в doctrine collection подробно, но я думаю, что проблема в том, что вы используете доступ к массиву в методе add note. Если вы вместо этого используете $this->notes->add($note)
, это должно сработать, так как вы установили каскадное сохранение. Вы также можете вручную задать идентификатор проблемы либо при создании заметки, либо в addNote() перед добавлением в массив / коллекцию.
Комментарии:
1. Спасибо за ваш ответ, Note действительно является стороной-владельцем, поэтому необходимо установить проблему для примечания (нет необходимости устанавливать идентификатор)
$note->setIssue($this)
, еще не протестированный с недавно созданной проблемой, у которой нет идентификатора, но Doctrine должна быть в состоянии выяснить это при сохранении.