在 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->idGenerator
的 doctrine\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"
,因此它无法从序列中获取下一个值.
我在 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->idGenerator
的 doctrine\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"
,因此它无法从序列中获取下一个值.