Olá, mais uma vez estou por aqui hehe
Eu estou fazendo alguns projetos para fixação do conteúdo. Finalizei a primeira carreira de PHP, ja iniciei a segunda, além de que ja coloquei na lista os cursos de Symfony e o plano de estudos do professor Vinícius.
Bem, em um dos casos que estou fazendo de estudo, simulei algo que preciso fazer no meu dia a dia: dar insert em uma tabela com unique constraint. Eu espero que ocorra erro por conta dessa constraint, pois não quero verificar se o dado ja existe ou não no banco antes de inserir, apenas quero realizar a inserção, se ele existir, que me ocorra o erro (a constraint é sobre uma coluna de hash indexada).
A minha situação pode ser exemplificada assim:
foreach($clientes as $cliente){
try{
$this->entityManager->persist($cliente);
$this->entityManager->flush();
}catch(Exception $e){
//salva o erro no banco
}
}
Quando ocorre a primeira exception por conta da unique constraint ela tem a segundo mensagem e stacktrace (respectivamente):
An exception occurred while executing 'INSERT...' SQLSTATE[23000]: Integrity constraint violation: 1062 Duplicate entry '(...)' for key 'column_name_unique'
dbal\lib\Doctrine\DBAL\DBALException.php(182): Doctrine\DBAL\Driver\AbstractMySQLDriver->convertException('An exception oc...', Object(Doctrine\DBAL\Driver\PDO\Exception))
Todavia, após ocorrer essa DBAL Exception, não é mais possível rodar a aplicação, visto que é da uma mensagem na tela dizendo algo como: The EntityManager is closed.
Fiz algumas pesquisas na internet e na documentação do Doctrine e modifiquei meu código, para que a cada tentativa de salvar a entidade eu verifique se a EntityManager está fechada. Caso ela esteja, então ela é recriada.
//Código da function que reabre a EntityManager
private function reopenEntityManager()
{
if (!$this->entityManager->isOpen()) {
$this->entityManager = $this->entityManager->create(
$this->entityManager->getConnection(),
$this->entityManager->getConfiguration()
);
}
}
//Código para persistir a entidade
foreach($clientes as $cliente){
try{
$this->reopenEntityManager();
$this->entityManager->persist($cliente);
$this->entityManager->flush();
}catch(Exception $e){
//salva o erro no banco
}
}
Assim, o erro que aparecia de a EntityManager estar fechada não ocorre mais e o foreach dá continuidade.
Todavia, quando a unique constraint é novamente violada, a exception salva não é a mesma que a relatava anteriormente, mas essa:
Undefined index: 000000005e09d9dc0000000049c307c7
Mesmo os registros que deveriam ser inseridos após o primeiro erro de unique constraint, não o são. Todas as tentativas passam a ter essa mensagem de exception, variando apenas o número do index, obviamente.
Além disso, a exception que deveria ocorrer era a mesma que ocorreu na primeira, quando fosse o caso de violação da unique constraint.
A impressão que eu tenho é a de que o Doctrine não está encontrando o objetos internos do objeto pai que estou salvando. Entretanto, ao executar os comandos de validação e para ver as informações, não aparece nenhum erro.
Observação.: Estou usando o Laravel com Doctrine. Mas coloquei essa dúvida aqui no tópico de doctrine pq acredito ser uma questão específica do doctrine, não do laravel. Não parece, ao menos, ter nenhuma relação com o Laravel.