19

有没有办法在持久/刷新之前获取实体 ID?我是说:

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

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

我可以通过以下方式使其工作:

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

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

我怎样才能做到这一点?

4

6 回答 6

33

如果您想在实体被持久化到数据库之前知道它的 ID,那么您显然不能使用生成的标识符。您需要找到某种方法来自己生成唯一标识符(也许某种散列函数可以产生足够唯一的值)。

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

我会非常仔细地考虑为什么我需要在刷新之前知道标识符。Doctrine 非常擅长让您构建一个大对象图,并一次性持久化/刷新它。您的架构中似乎有一些丑陋的东西需要解决。在使用 application-generated-id 路由之前查看它可能是一个好主意。

于 2012-05-08T20:48:39.087 回答
12

您可以使用 @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.

         $this->doSomething($this->id);
     }
    
     ...

}
于 2017-06-20T00:46:33.963 回答
1

教义最佳实践说,

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

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

所以你可以使用 UUIDS

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

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

于 2020-01-23T12:41:45.683 回答
1
$em = $this->getDoctrine()->getManager();
$entity = new PointData();

$em->persist($entity);

$entity->getId() <-- return <int>

$em->flush();

坚持后你可以得到id

于 2020-02-08T17:50:40.450 回答
0

你可以使用自动生成的 ID 来获取一个键,比如通用唯一标识符 (UUID),或者你可以获取 symfony 的事件: postFlush - postFlush 事件在刷新操作结束时发生。

于 2018-09-06T16:01:26.670 回答
0

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

尝试这样的事情:

$em->beginTransaction();
$em->persist($entity);
$em->flush();
$id = $entity->getId();
//do some stuff and save when ready
$em->commit();
于 2021-04-28T08:19:57.763 回答