2012-10-04 23 views
2

我想更改實體值,例如,如果它是例如NULL。 不幸的是,我的代碼會導致異常 - 雖然在數據庫中創建了'翻譯'記錄,並且id由getId方法正確返回,但似乎沒有設置id。如何在使用Symfony2保存之前設置或更改實體值

這是相當簡單的代碼,爲什麼它不起作用?

public function createAction(Request $request) 
{ 
    $entity = new Word(); 
    $form = $this->createForm(new WordType(), $entity); 
    $form->bind($request); 


    if ($form->isValid()) { 

     $em = $this->getDoctrine()->getManager(); 

     //works fine - database record is created 
     if($entity->getIdTranslation() == NULL){ 
      $translation = new Translation(); 
      $em->persist($translation); 
      $em->flush(); 
      $entity->setIdTranslation($translation->getId()); 
     } 


     $em->persist($entity); 
     //throws exception - Integrity constraint violation: 1048 Column 'id_translation' cannot be null 
     $em->flush(); 

     return $this->redirect($this->generateUrl('admin_word_show', array('id' => $entity->getId()))); 
    } 

    return array(
     'entity' => $entity, 
     'form' => $form->createView(), 
    ); 
} 

編輯:加入我的模型和映射信息的一部分:

part of model for overwiev

Revelant詞映射:

/** 
* @var integer $id_language 
* 
* @ORM\Column(name="id_language", type="integer") 
*/ 
private $id_language; 
/** 
*@ORM\ManyToOne(targetEntity="Language", inversedBy="words") 
*@ORM\JoinColumn (name="id_language", referencedColumnName="id") 
*/ 
protected $language; 

/** 
* 
* @ORM\ManyToOne(targetEntity="Translation", inversedBy="words") 
* @ORM\JoinColumn(name="id_translation", referencedColumnName="id") 
*/ 
protected $translation; 

和翻譯:

class Translation 
{ 

public function __construct() { 
    $this->words = new ArrayCollection(); 
} 
/** 
* @ORM\PrePersist() 
*/ 
public function prePersist() { 
    $this->created_date = new \DateTime(); 
} 
/** 
* 
* @ORM\OneToMany(targetEntity="Word" ,mappedBy="translation") 
*/ 
protected $words; 

另請注意: 我使用數據庫建模軟件(工作臺)而不是Symfony控制檯工具創建了我的數據庫模型,現在我試圖設置實體以反映數據庫模型。 我不確定它的正確方法 - 也許我的模型太複雜,無法與教義正常工作?

+1

您能顯示實體原則映射嗎? – l3l0

+0

問題更新 – stawek

回答

8

生命週期回調

有時候,你需要正確的之前或實體插入,更新後要執行的操作,或刪除。這些類型的操作稱爲「生命週期」回調,因爲它們是您需要在實體的生命週期的不同階段(例如實體被插入,更新,刪除等)執行的回調方法。

生命週期回調應該是簡單的方法是關注於實體內部轉換數據(例如設置創建/更新的領域,產生廢料值)

如果你需要做一些更重的起重 - 像執行日誌記錄或發送電子郵件 - 您應該註冊一個外部類作爲事件監聽器或訂戶,並讓它訪問您需要的任何資源。欲瞭解更多信息,請參閱如何註冊a Event Listeners and Subscribers.

+1

關於此的Doctrine文檔可在以下位置找到:http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/reference/events.html#lifecycle-events。 Symfony文檔位於:http://symfony.com/doc/current/book/doctrine.html。不要忘記,如果您在php中使用註釋,您需要將 '/ ** * @ORM \ Entity() * @ORM \ HasLifecycleCallbacks() * /' 添加到您的文檔標題。 –

1

這樣做的一個更好的地方是Word類的構造函數:

class Word 
{ 
    /** 
    * @OneToOne(targetEntity="Translation", cascade={"persist"}) 
    */ 
    private $translation; 

    public function __construct() 
    { 
     $this->translation = new Translation; 
    } 
} 

順便說一句,你並不需要,因爲它是由學說處理手動堅持翻譯ID。

$word = new Word; 

$em->persist($word); 
$em->flush(); 

$translation = $word->getTranslation(); 
$translationId = $translation->getId(); 
+0

感謝響應和有用的信息,但在我的情況我希望能夠創造新的翻譯,如果它不是已經給 - 即id_translation爲空,我嘗試使用prePersist的做法,但結束了講述EM不可用錯誤在實體範圍內。那麼也許我應該閱讀更多的文檔,而不是試圖通過創建示例項目來學習框架。 – stawek

相關問題