Doctrine2 - 在刷新之前获取实体ID

时间:2012-05-07 16:24:34

标签: doctrine-orm entity flush persist

有没有办法在persist / flush之前获取实体ID? 我的意思是:

$entity = new PointData();
$form   = $this->createForm(new PointDataType(), $entity);

如果我此时尝试 $ entity-> getId(),则不返回任何内容。

我可以通过以下方式开展工作:

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

(假设 $ em = $ this-> getDoctrine() - > getEntityManager();

我怎样才能做到这一点?

6 个答案:

答案 0 :(得分:23)

如果您想知道实体在持久存储到数据库之前的ID,那么您显然无法使用生成的标识符。您需要找到一些方法来自己生成唯一标识符(也许某种哈希函数可以生成唯一足够的值)。

但这不是一个好主意,所以你应该小心。

我会非常仔细地考虑为什么我需要在刷新之前知道标识符。 Doctrine非常善于让你构建一个大对象图,并立即持久/冲洗它。看起来很可能你的架构中有一些丑陋的东西正在试图解决。在关闭application-generated-id路由之前,最好先查看一下。

答案 1 :(得分:6)

您可以使用@PostPersist注释。使用该方法注释的方法将在刷新终止之前执行,并且实体Id已经可用。

https://www.doctrine-project.org/projects/doctrine-orm/en/2.6/reference/events.html

postPersist - 在实体持久化后,实体发生postPersist事件。它将在数据库插入操作后调用。 postPersist事件中提供了生成的主键值。

<?php

use Doctrine\ORM\Mapping as ORM;

/** 
 * @ORM\Entity 
 * @ORM\HasLifecycleCallbacks 
 */
class PointData
{
    /**
     * @ORM\Column(name="id", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
     private $id;

     ...

     /** 
      * @ORM\PostPersist 
      */
     public function onPostPersist()
     {
         // Put some simple logic here that required the auto-generated Id.
     }

     ...

}

答案 2 :(得分:1)

Doctrine best practices说,

您应避免自动生成标识符。因为:

  • 您的数据库操作将互相阻塞
  • 您拒绝批量插入
  • 您无法进行多请求交易
  • 您的对象在保存之前是无效的
  • 没有数据库,您的对象将无法工作

因此您可以改用 UUIDS

public function __construct() {
     $this->id = Uuid::uuid4();  
}

此外,Doctrine自2.3版开始支持UUID生成策略。

答案 3 :(得分:1)

    private void btnCopyStyles_AttachTemplate_Click(object sender, EventArgs e)
    {
        string tmplPath  = @"C:\Test\StylesTemplate.dotm";
        Word.Document doc = wdApp.ActiveDocument;
        doc.set_AttachedTemplate(tmplPath);
        doc.UpdateStyles();
    }

坚持后,您可以获取ID

答案 4 :(得分:0)

您可以使用自动生成的ID来获取密钥(例如通用唯一标识符(UUID)),也可以采取symfony事件:  postFlush-postFlush事件在刷新操作结束时发生。

答案 5 :(得分:0)

不确定为什么在刷新之前需要 ID,但是,如果您确实需要在不保存到数据库的情况下持久保存实体,则可以尝试使用 Transactions

尝试这样的事情:

$em->beginTransaction();
$em->persist($entity);
$em->flush();
$id = $entity->getId();
//do some stuff and save when ready
$em->commit();