学说:如何保持ids的独特性?

时间:2016-07-14 12:28:24

标签: sqlite orm doctrine-orm symfony

我面临的问题是我无法强制 doctrine 为新对象发布新的ID。例如:

/**
 * Something
 *
 * @ORM\Table(name="something")
 * @ORM\Entity
 */
class Something
{
    /**
     * @var integer
     *
     * @ORM\Column(name="id", type="integer", nullable=false)
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="IDENTITY")
     */
    protected $id;
}

显然会生成唯一的ID - 但是当对象稍后被删除时,该id将用于稍后生成的对象。这是不幸的,因为可能存在关于引用该id的链接,该ID现在指向错误的对象而不是仅仅失败。

在没有 doctrine 的情况下直接在数据库上工作时,我使用的是autoincrement,它按预期工作。但是,使用 doctrine 来管理表格似乎不起作用。

使用strategy="UUID"是有帮助的,而且往往是更好的选择,但有时候这是不可行的。例如,bundle FOSUserBundle 似乎依赖整数来表示用户的id。这基本上意味着a)永远不会删除用户但只是停用它们,或者b)添加另一个id / key(对于依赖于该人工id的关系而言非常hacky)。

是否可以强制使用新的整数ID? (使用 FOSBundle 使用UUID的方法会很好,但我不认为这是可以实现的。)

目前在OS X上的symfony 3.1.2中使用doctrine 2.5.4和sqlite - 但生产服务器将基于linux。在PHP 7.0上运行。

1 个答案:

答案 0 :(得分:1)

Doctrine应根据Doctrine documentation在sqlite数据库上将GeneratedValue(strategy="IDENTITY")映射到AUTOINCREMENT,因此没有Doctrine的尝试应该没有区别。

事实上,AUTOINCREMENT的标识列只应重新使用生成的数字,如果生成它的事务被回滚(请参阅https://sqlite.org/autoinc.html)。在这种情况下,不应在其他条目中使用该号码,因为它们也应该回滚。

所以我认为使用GeneratedValue(strategy="IDENTITY")没有问题,至少如果你使用交易。

修改

bug in Doctrine2阻止GeneratedValue(strategy="IDENTITY")正常工作,但a workaround存在,为EventSubscriber事件注册了onSchemaCreateTable。它创建了正确的sql来生成主键列上具有AUTOINCREMENT属性的表。