Doctrine orm 触发自动生成新实体上的字段(Symfony中的条令)/避免完整性约束冲突字段不能为空

Doctrine orm 触发自动生成新实体上的字段(Symfony中的条令)/避免完整性约束冲突字段不能为空,doctrine-orm,doctrine,symfony,auto-generate,Doctrine Orm,Doctrine,Symfony,Auto Generate,在使用Symfony 3.x和Doctrine时,我遇到了以下问题: 实体“Foo”的定义如下: /** * @ORM\Entity * @ORM\Table(name="foo") */ class Foo { /** * @ORM\Id * @ORM\Column(type="integer") * @ORM\GeneratedValue(strategy="AUTO") */ protected $id; /**

在使用Symfony 3.x和Doctrine时,我遇到了以下问题: 实体“Foo”的定义如下:

/**
 * @ORM\Entity
 * @ORM\Table(name="foo")
 */
class Foo
{
    /**
     * @ORM\Id
     * @ORM\Column(type="integer")
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    protected $id;

    /**
     * @ORM\Column(type="integer")
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    protected $incr_int;

    ...
}
撇开$id和$incr_int(始终?)将是相同的值不谈,在创建类型为Foo的新实体时,我会遇到以下错误:

An exception occurred while executing 'INSERT INTO foo (incr_int) VALUES (?)' with params [null]:

SQLSTATE[23000]: Integrity constraint violation: 1048 Column 'incr_int' cannot be null
虽然从错误本身来看这似乎是有道理的,但在创建这样的Foo时,我不知道如何修复它(我相信这是Symfony中的标准方式):


如果我从Foo中删除$incr_int字段,我希望它能起作用,因为唯一剩余的字段$id是通过将最后插入的id值增加1自动生成的。我假设$incr_int字段的这种行为应该是相同的。好。。。显然不是,我也不知道为什么。非常感谢您的帮助。

我的代码中有两个问题(感谢@nospor)

  • 一个表只能有一个自动递增字段(第二个字段无论如何都没有多大意义)
  • 创建新实体时,在实际更新DB(刷新实体管理器)时生成id

  • 我可以通过删除第二个自动递增条件,创建具有必需字段(这里仅为自动生成的id字段)的实体,然后刷新它来解决这个问题。刷新后,我可以检索id并生成第二个字段的值,其中包含一个计算值,该值也取决于id值。

    为什么需要两个自动递增字段?如果需要,这意味着数据库中的逻辑不正确。“自动递增字段在一个表中只能有一次。@nospor这是否意味着在一个表中通常不可能有两个自动递增字段?”?那么。。。好的:-)我真正需要的是一个唯一的整数字段,它保存从1000开始的递增值…为什么需要1000+?您知道,您可以在PHP中将1000个数字添加到ID?;)或者您可以为自动增量设置
    initialValue
    @nospor这就是我正在做的atm(PHP中的+1000),但是我想把这个逻辑转移到DB/doctor。initialValue只适用于不幸的是MySql无法使用的序列(作为第一件事尝试)。但是:现在我有一个问题,要检索自动生成的id字段,我必须首先刷新实体管理器。但是刷新需要设置其他依赖于id的必填字段。。。我该如何解决这个问题?@user3440145不客气:)并且不加解释地谈论向下投票:这是这里的常见做法,所以要习惯它;)是的,但由于此流程需要查询,我建议您重新考虑ID的使用,并保留第二个唯一字符串,而不使用它。。。只是一个建议:)@Aerendir Hm y-但是我需要第二个唯一的字符串来包含序列号。这似乎是使用id字段的最佳理由。不是吗?Oterhwise我必须生成一个序列并存储最后的数字和东西-这似乎比现在的方式更费劲(而且性能更低)…你能更好地解释“序列”是什么意思吗?因为它可能意味着“1,2,3,4”之类的意思,或者它可能是“1,3,4,7,10…”之类的意思。区别是非常重要的:在第一种情况下,当前的解决方案可能有效(然后,有时间重构代码以提高性能)。相反,如果不需要精确的序列,可以使用\DateTime和微秒精度来确保序列号是唯一的和连续的…例如:
    $time=\DateTime::createFromFormat('U.U',microtime(true))
    然后
    $time->format('YmdHisu')
    。我使用最后一个解决方案为发票生成唯一的序列号。也许这对你也有帮助。无论如何,ID的使用并不能保证第一种顺序,因为有些实体可能会被删除,所以结果可能不是一个真正的序列。。。
    $foo = new Foo();
    $em->persist($foo);     // $em is the entity manager
    $em->flush();