Doctrine один ко многим невозможно выполнить каскадное сохранение, потому что идентификатор не предоставлен Doctrine

#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 должна быть в состоянии выяснить это при сохранении.