在 Oracle 中使用 "SEQUENCE" 作为 GeneratedValue 时 Symfony Doctrine 不起作用

Symfony Doctrine not working when uses "SEQUENCE" as GeneratedValue in Oracle

我在 Symfony 2 中有以下实体,其 ID 由 Oracle 序列生成:

namespace PSBundle\Entity;

use Doctrine\ORM\Mapping as ORM;

/**
 * @ORM\Table(name="CONTRATO")
 * @ORM\Entity
 * @ORM\Entity(repositoryClass="PSBundle\Entity\ContratoRepository")
 */
class Contrato
{
    /**
     * @var integer
     *
     * @ORM\Column(name="ID_CONTRATO", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="SEQUENCE")
     * @ORM\SequenceGenerator(sequenceName="SID_CONTRATO", allocationSize=1, initialValue=1)
     */
    private $idContrato;

    // Other fields...
}

但是当我这样做时:

$entityContrato = new Contrato();
// Set some fields
$em->persist($entityContrato);

我得到:

Entity of type PSBundle\Entity\Contrato is missing an assigned ID for field 'idContrato'. The identifier generation strategy for this entity requires the ID field to be populated before EntityManager#persist() is called. If you want automatically generated identifiers instead you need to adjust the metadata mapping accordingly.

我知道 SID_CONTRATO 定义明确,就好像我 select NEXTVAL 一样有效:

我错过了什么?主题中的任何一种光线都将不胜感激,我的相关依赖项是:

"php": "7.2",
"symfony/symfony": "2.3.42",
"doctrine/orm": "2.3.x-dev",
"doctrine/doctrine-bundle": "1.2.0",

Doctrine 配置(来自 config/config.yml,我没有 doctrine.yaml 文件):

# Doctrine Configuration
doctrine:
    dbal:
        driver:   oci8
        port:     1521
        dbname:   ORCL
        host:     %dbal_host%
        user:     %dbal_user%
        password: %dbal_pass%
        charset:  UTF8
        memory: true

        logging: true

    orm:
        auto_generate_proxy_classes: %kernel.debug%
        auto_mapping: true

# IMPORTANT: this fixes bugs with the date format that is brought from Oracle ('d/m/y')
# The problem is described here:  
services:
    oracle.listener:
        class: Doctrine\DBAL\Event\Listeners\OracleSessionInit
        tags:
            - { name: doctrine.event_listener, event: postConnect }

好的,我找到问题了:

如果我在 $class->idGeneratordoctrine\orm\lib\Doctrine\ORM\UnitOfWork.php 中执行 var_dump(),它会输出:

object(Doctrine\ORM\Id\AssignedGenerator)

而如果我对当前使用序列的实体执行相同操作,它们会输出:

object(Doctrine\ORM\Id\SequenceGenerator)...

所以 Symfony 没有获得正确类型的生成器。我检查实体文件,发现有一些字段带有@ORM\GeneratedValue(strategy="NONE"),例如:

/**
 * @var integer
 *
 * @ORM\Column(name="ID_CONTRATO", type="integer", nullable=false)
 * @ORM\Id
 * @ORM\GeneratedValue(strategy="SEQUENCE")
 * @ORM\SequenceGenerator(sequenceName="SID_CONTRATO", allocationSize=1, initialValue=1)
 */
private $idContrato;

/**
 * @var string
 *
 * @ORM\Column(name="TIPO", type="string", length=1, nullable=false)
 * @ORM\GeneratedValue(strategy="NONE")  // This was the conflicting line
 */
private $tipo;

显然,Symfony 将最后一个 @ORM\GeneratedValue 定义作为 class 标识符生成器,​​在本例中它具有 strategy="NONE",因此它无法从序列中获取下一个值.