web-dev-qa-db-fra.com

Doctrine - Une nouvelle entité a été trouvée dans la relation

depuis 2 semaines, nous rencontrons ce problème en essayant de vider de nouveaux éléments:

CRITICAL: Doctrine\ORM\ORMInvalidArgumentException:

Une nouvelle entité a été trouvée dans la relation 'Commentaire # capture' qui n'était pas configurée pour mettre en cascade des opérations persistantes pour l'entité.

Mais la variable capture est déjà dans la base de données, et nous l’obtenons par une variable findOneBy. Par conséquent, si nous persistons en cascade, ou persistons,

Violation de contrainte de table: entrée en double.

Les commentaires sont créés en boucle avec différentes captures, avec un nouveau et tous les champs requis sont définis.

Avec toutes les entités persistantes et/ou obtenues par un findOne (et toutes valides), le flush échoue toujours.

Je suis sur cette question depuis un moment, alors aidez-moi s'il vous plaît

59
isundil

J'ai eu le même problème et c'était la même EntityManager. Je voulais insérer un objet lié ManyToOne. Et je ne veux pas de cascadepersist.

Exemple : 

$category = $em->find("Category", 10);

$product = new Product();
$product->setCategory($category)

$em->persist($product);
$em->flush();

Cela jette la même exception pour moi. 

La solution est donc:

$category = $em->find("Category", 10);

$product = new Product();
$product->setCategory($category)

$em->merge($product);
$em->flush();
47
Mirza Selimovic

Dans mon cas, un appel trop tôt de 

$this->entityManager->clear();

causé le problème. Il a également disparu en ne faisant que clarifier l’objet récent, comme

$this->entityManager->clear($capture);
39
ownking

Ma réponse est pertinente pour le sujet, mais pas très pertinente pour votre cas particulier, donc je poste ceci pour ceux sur Google, car les réponses ci-dessus ne m'ont pas aidé.

Dans mon cas, j'ai eu la même erreur avec les entités de traitement par lots qui avaient une relation et cette relation était définie sur la même entité.

CE QUE JE DID FAUX:

Lorsque je maîtrisais $this->entityManager->clear(); lors du traitement d’un lot d’entités, j’obtenais cette erreur, car le lot d’entités suivant indiquerait l’entité associée détachée. 

QU'EST CE QUI NE S'EST PAS BIEN PASSÉ:

  1. Je ne savais pas que $this->entityManager->clear(); fonctionnait de la même manière que $this->entityManager->detach($entity); ne détache que TOUTES les entités du référentiel.

  2. Je pensais que $this->entityManager->clear(); détache également des entités liées.

CE QUE J'AI DEVRAIT FAIRE:

J'aurais dû itérer sur les entités et les détacher une par une - cela ne détacherait pas l'entité associée désignée par les futures entités. 

J'espère que ça aidera quelqu'un.

25
drakonli

Tout d’abord, vous devriez mieux prendre soin de votre code, je vois trois indentations différentes dans votre entité et dans votre contrôleur - ceci est difficile à lire et ne correspond pas aux normes de codf Symfony2

Le code vous indiquez pour votre contrôleur n’est pas complet, nous ne savons pas d’où vient $this->activeCapture. Vous avez à l'intérieur un $people['capture'] qui contient un objet Capture que je présume. C'est très important.

Si la capture dans $people['capture'] est persistée/extraite d'un autre EntityManager que $this->entityManager (nous ne savons pas d'où elle vient), Doctrine2 n'a aucune idée que l'objet est déjà persistant.

Assurez-vous d'utiliser la même instance de Doctrine Entity Manager pour toutes ces opérations (utilisez spl_object_hash sur l'objet EM pour vous assurer qu'il s'agit bien de la même instance).

Vous pouvez également indiquer à EntityManager quoi faire avec l'objet Capture.

// Refreshes the persistent state of an entity from the database
$this->entityManager->refresh($captureEntity);

// Or
// Merges the state of a detached entity into the 
// persistence context of this EntityManager and returns the managed copy of the entity.
$captureEntity = $this->entityManager->merge($captureEntity);

Si cela ne vous aide pas, vous devez fournir plus de code.

9
Damien

L'erreur: 'Commentaire # capture' qui n'a pas été configuré pour mettre en cascade les opérations persistantes pour l'entité 

Le problème:

/**
 * @ORM\ManyToOne(targetEntity="Capture", inversedBy="comments")
 * @ORM\JoinColumn(name="capture_id", referencedColumnName="id",nullable=true)
 */
 protected $capture;

ne pas configuré la persistance de la cascade

essayez avec ceci:

/**
 * @ORM\ManyToOne(targetEntity="Capture", inversedBy="comments", cascade={"persist", "remove" })
 * @ORM\JoinColumn(name="capture_id", referencedColumnName="id",nullable=true)
 */
 protected $capture;
6
Roberto

J'ai aussi eu cette erreur quand j'ai essayé de ajouter un nouveau entité. 

A new entity was found through the relationship 'Application\Entity\User#chats' 
that was not configured to cascade persist operations for entity: ###. 
To solve this issue: Either explicitly call EntityManager#persist() on this unknown entity or
configure cascade persist  this association in the mapping for example @ManyToOne(..,cascade={"persist"}).

Mon cas était que j'ai essayé de sauver l'entité, cela ne devrait pas être sauvé. Les relations entre entités étaient remplies et essayaient d'être sauvegardées (User a Chat dans Many2Many, mais Chat était une entité temporaire), mais il y a eu quelques collisions. 

Donc, si j'utilise cascade={"persist"}, j'obtiens un comportement indésirable: l'entité de la corbeille est enregistrée. Ma solution consistait à supprimer l'entité qui ne sauvegarde pas des entités de sauvegarde:

// User entity code
public function removeFromChats(Chat $c = null){
    if ($c and $this->chats->contains($c)) {
        $this->chats->removeElement($c);
    }
}

Code d'enregistrement

/* some code witch $chat entity */
$chat->addUser($user);

// saving
$user->removeFromChats($chat);
$this->getEntityManager()->persist($user);
$this->getEntityManager()->flush();
0
shukshin.ivan

Rafraîchir l'entité en question a aidé mon cas.

/* $item->getProduct() is already set */

/* Add these 3 lines anyway */
$id = $item->getProduct()->getId();            
$reference = $this->getDoctrine()->getReference(Product::class, $id);
$item->setProduct($reference);

/* Original code as follows */
$quote->getItems()->add($item);
$this->getDoctrine()->persist($quote);
$this->getDoctrine()->flush();

Bien que mon $item ait déjà un Product défini ailleurs (il s'avère que cela a été défini via une différente instance de EntityManager), je continuais à recevoir l'erreur. 

Il s’agit donc d’un hack, en récupérant id du produit existant, puis en récupérant une référence, et en utilisant setProduct pour "rafraîchir" la connexion quelconque. Je l'ai corrigé plus tard en m'assurant de n'avoir qu'une seule instance de EntityManager dans mon code.

0
Dennis