Minha entidade usa esta anotação para seu ID:
/**
* @orm:Id
* @orm:Column(type="integer")
* @orm:GeneratedValue(strategy="AUTO")
*/
protected $id;
De um banco de dados limpo, estou importando registros existentes de um banco de dados mais antigo e tentando manter os mesmos IDs. Então, ao adicionar novos registros, quero que o MySQL incremente automaticamente a coluna ID como de costume.
Infelizmente, parece que o Doctrine2 ignora completamente o ID especificado.
Nova Solução
De acordo com as recomendações abaixo, o seguinte é a solução preferida:
$this->em->persist($entity);
$metadata = $this->em->getClassMetaData(get_class($entity));
$metadata->setIdGeneratorType(\Doctrine\ORM\Mapping\ClassMetadata::GENERATOR_TYPE_NONE);
$metadata->setIdGenerator(new \Doctrine\ORM\Id\AssignedGenerator());
Solução Antiga
Como o Doctrine se baseia no ClassMetaData para determinar a estratégia do gerador, ele deve ser modificado após o gerenciamento da entidade no EntityManager:
$this->em->persist($entity);
$metadata = $this->em->getClassMetaData(get_class($entity));
$metadata->setIdGeneratorType(\Doctrine\ORM\Mapping\ClassMetadata::GENERATOR_TYPE_NONE);
$this->em->flush();
Acabei de testar isso no MySQL e funcionou conforme o esperado, o que significa que entidades com um ID personalizado foram armazenados com esse ID, enquanto aquelas sem um ID especificado usaram o lastGeneratedId() + 1
.
fonte
$metadata = $this->getEntityManager()->getClassMetaData(User::class); $metadata->setIdGenerator(new AssignedGenerator()); $metadata->setIdGeneratorType(ClassMetadata::GENERATOR_TYPE_NONE);
Respostas:
Embora sua solução funcione bem com o MySQL, não consegui fazê-la funcionar com o PostgreSQL porque é baseado em sequência.
Tenho que adicionar esta linha para que funcione perfeitamente:
$metadata->setIdGenerator(new \Doctrine\ORM\Id\AssignedGenerator());
Cumprimentos,
fonte
$em->persist($entity)
.Talvez o que a doutrina mudou, mas agora o caminho certo é:
fonte
ClassMetadata
é uma interface e portanto não pode ter nenhuma constante.$metadata::GENERATOR_TYPE_NONE
No caso da entidade fazer parte de uma herança de tabela de classe, você precisa alterar o gerador de id nos metadados de classe para ambas as entidades (a entidade que você está persistindo e a entidade raiz)
fonte
SQLSTATE[23000]: Integrity constraint violation: 1452 Cannot add or update a child row: a foreign key constraint fails
erros. DownvotedA nova solução funciona bem apenas quando TODAS as entidades têm id antes da inserção. Quando uma entidade tem ID e outra não - a nova solução está falhando.
Eu uso esta função para importar todos os meus dados:
fonte
Solução para Doctrine 2.5 e MySQL
A "Nova solução" não funciona com Doctrine 2.5 e MySQL. Você tem que usar:
No entanto, só posso confirmar isso para o MySQL, porque ainda não experimentei nenhum outro DBMS.
fonte
Eu criei uma biblioteca para definir IDs futuros para entidades Doctrine. Ele reverte para a estratégia de geração de ID original quando todos os IDs enfileirados são consumidos para minimizar o impacto. Deve ser uma entrada fácil para testes de unidade, para que um código como este não precise ser repetido.
fonte
Inspirado no trabalho de Villermen , criei a biblioteca tseho / doctrine -assign-identity que permite atribuir manualmente IDs a uma entidade Doctrine, mesmo quando a entidade usa as estratégias AUTO, SEQUENCE, IDENTITY ou UUID.
Você nunca deve usá-lo na produção, mas é muito útil para testes funcionais.
A biblioteca detectará automaticamente as entidades com um id atribuído e substituirá o gerador apenas quando necessário. A biblioteca terá um fallback no gerador inicial quando uma instância não tiver um ID atribuído.
A substituição do gerador ocorre em um Doctrine EventListener, sem necessidade de adicionar qualquer código adicional em seus acessórios.
fonte