简体   繁体   English

如何在使用Symfony2保存之前设置或更改实体值

[英]How to set or change entity value before saving using Symfony2

I would like to change entity value in case if it's for example NULL. 如果它是例如NULL,我想更改实体值。 Unfortunately my code causes exception - it seems that id isn't set although 'translation' record is created in database and id is properly returned by getId method. 不幸的是我的代码导致异常 - 虽然在数据库中创建了'translation'记录并且getId方法正确返回了id,但似乎没有设置id。

It's quite simple code, why it doesn't work? 这是非常简单的代码,为什么它不起作用?

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(),
    );
}

Edit: added part of my model and mappings info: 编辑:添加了我的模型和映射信息的一部分:

过度模型的一部分

Revelant Words mappings: Revelant Words mappings:

 /**
 * @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;

and Translations: 和翻译:

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;

Also on side note: I'v created my db model using database modeling software (workbench) not by Symfony console tools and now I'm trying to setup Entities to reflect db model. 另外注意:我使用数据库建模软件(工作台)而不是Symfony控制台工具创建了我的数据库模型,现在我正在尝试设置实体以反映数据库模型。 I'm not sure if its right approach - maybe my model is too complicated to work properly with Doctrine? 我不确定它的正确方法 - 也许我的模型太复杂而无法与Doctrine一起使用?

Lifecycle Callbacks 生命周期回调

Sometimes, you need to perform an action right before or after an entity is inserted, updated, or deleted . 有时,您需要在插入,更新或删除实体之前或之后执行操作。 These types of actions are known as " lifecycle " callbacks, as they're callback methods that you need to execute during different stages of the lifecycle of an entity (eg the entity is inserted, updated, deleted, etc). 这些类型的操作称为“ 生命周期 ”回调,因为它们是您需要在实体生命周期的不同阶段执行的回调方法(例如,插入,更新,删除实体等)。

Lifecycle callbacks should be simple methods that are concerned with internally transforming data in the entity (eg setting a created/updated field, generating a slug value) 生命周期回调应该是与内部转换实体中的数据有关的简单方法 (例如,设置创建/更新的字段,生成段塞值)

If you need to do some heavier lifting - like perform logging or send an email - you should register an external class as an event listener or subscriber and give it access to whatever resources you need. 如果你需要做一些更重的提升 - 比如执行记录或发送电子邮件 - 你应该将外部注册为事件监听器或订阅者,并让它访问你需要的任何资源。 For more information, see How to Register a Event Listeners and Subscribers. 有关更多信息,请参阅如何注册事件监听器和订户。

A better place for this is the Word class's constructor: 更好的地方是Word类的构造函数:

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

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

BTW, you don't need to persist the translations ID manually because it's handled by Doctrine. 顺便说一句,您不需要手动保留翻译ID,因为它是由Doctrine处理的。

$word = new Word;

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

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM