【问题标题】:How to set or change entity value before saving using Symfony2如何在使用 Symfony2 保存之前设置或更改实体值
【发布时间】:2012-09-26 01:26:21
【问题描述】:

我想更改实体值,以防它是例如 NULL。 不幸的是,我的代码导致异常 - 尽管在数据库中创建了“翻译”记录并且 id 由 getId 方法正确返回,但似乎没有设置 id。

很简单的代码,为什么不起作用?

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

编辑:添加了我的模型和映射信息的一部分:

相关词映射:

 /**
 * @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 控制台工具创建了我的数据库模型,现在我正在尝试设置实体以反映数据库模型。 我不确定它的方法是否正确 - 也许我的模型太复杂而无法与 Doctrine 一起正常工作?

【问题讨论】:

  • 你能展示实体学说映射吗?

标签: php symfony doctrine-orm entity


【解决方案1】:

生命周期回调

有时,您需要在插入、更新或删除实体之前或之后执行操作。这些类型的操作称为“生命周期”回调,因为它们是您需要在实体生命周期的不同阶段执行的回调方法(例如,插入、更新、删除实体,等)。

生命周期回调应该是涉及在实体内部转换数据的简单方法(例如,设置创建/更新字段、生成 slug 值)

如果您需要做一些更繁重的工作 - 例如执行日志记录或发送电子邮件 - 您应该注册一个外部 类作为事件侦听器 或订阅者,并允许它访问您需要的任何资源。更多信息,请参阅如何注册a Event Listeners and Subscribers.

【讨论】:

【解决方案2】:

一个更好的地方是 Word 类的构造函数:

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

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

顺便说一句,您不需要手动保存翻译 ID,因为它是由 Doctrine 处理的。

$word = new Word;

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

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

【讨论】:

  • 感谢您的回复和有用的信息,但在我的场景中,如果尚未提供新翻译,我希望能够创建新翻译 - 即 id_translation 为空,我尝试使用 prePersist 方法但最终出现错误提示关于 em 在实体范围内不可用。好吧,也许我应该阅读更多文档,而不是尝试通过创建示例项目来学习框架。
猜你喜欢
  • 1970-01-01
  • 2012-10-25
  • 2023-03-03
  • 1970-01-01
  • 1970-01-01
  • 2021-08-08
  • 1970-01-01
  • 2021-01-30
  • 1970-01-01
相关资源
最近更新 更多