主义-一个新的实体被发现通过关系

自2周以来,我们在尝试冲洗新元素时遇到了这个问题:

例外:

一个新的实体被发现通过关系“注释 # 捕获”,没有配置级联持久化操作的实体

但是 capture已经在数据库中了,我们通过 findOneBy得到它,所以如果我们级联持久化它,或者持久化它,我们得到一个

表约束违反: 重复条目。

注释是在一个循环中创建的,其中包含不同的捕获,并且设置了一个新的、所有必需的字段。

当所有实体都被持久化和/或通过 findOne获得(并且都是有效的)时,刷新仍然会失败。

我在这个问题上已经有一段时间了,所以请帮帮我

110142 次浏览

First of all, you should take better care of your code, I see like 3 differents indentations in your entity and controller - this is hard to read, and do not fit the Symfony2 coding standards.

The code you show for your controller is not complete, we have no idea from where $this->activeCapture is coming. Inside you have a $people['capture'] which contains a Capture object I presume. This is very important.

If the Capture in $people['capture'] is persisted / fetched from another EntityManager than $this->entityManager (which, again, we do not know from where it come), Doctrine2 have no idea that the object is already persisted.

You should make sure to use the same instance of the Doctrine Entity Manager for all those operations (use spl_object_hash on the EM object to make sure they are the same instance).

You can also tell the EntityManager what to do with the Capture object.

// 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);

If this does not help, you should provide more code.

The error: 'Comment#capture' that was not configured to cascade persist operations for entity

The problem:

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

dont configured the cascade persist

try with this:

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

In my case a too early call of

$this->entityManager->clear();

caused the problem. It also disappeared by only doing a clear on the recent object, like

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

I had the same problem and it was the same EntityManager. I wanted to insert an object related ManyToOne. And I don't want a cascade persist.

Example :

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


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


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

This throws the same exception for me.

So the solution is :

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


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


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

I got this error too when tried to add new entity.

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"}).

My case was that I tried to save entity, that shouldn't be saved. Entity relations was filled and tried to be saved (User has Chat in Many2Many, but Chat was a temporary entity), but there were some collisions.

So If I use cascade={"persist"} I get unwanted behaviour - trash entity is saved. My solution was to remove non-saving entity out of any saving entities:

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

Saving code

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


// saving
$user->removeFromChats($chat);
$this->getEntityManager()->persist($user);
$this->getEntityManager()->flush();

My answer is relevant for topic, but not very relevant for your particular case, so for those googling I post this, as the answers above did not help me.

In my case, I had the same error with batch-processing entities that had a relation and that relation was set to the very same entity.

WHAT I DID WRONG:

When I did $this->entityManager->clear(); while processing batch of entities I would get this error, because next batch of entities would point to the detached related entity.

WHAT WENT WRONG:

  1. I did not know that $this->entityManager->clear(); works the same as $this->entityManager->detach($entity); only detaches ALL of the repositorie`s entities.

  2. I thought that $this->entityManager->clear(); also detaches related entities.

WHAT I SHOULD HAVE DONE:

I should have iterated over entities and detach them one by one - that would not detach the related entity that the future entities pointed to.

I hope this helps someone.

Refreshing the entity in question helped my case.

/* $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();

Despite my $item already having a Product set elsewhere, I was still getting the error.

Turns out it was set via a different instance of EntityManager.

So this is a hack of sorts, by retrieving id of the existing product, and then retrieving a reference of it, and using setProduct to "refresh" the whatever connection. I later fixed it by ensuring I have and use only a single instance of EntityManager in my codebase.

I want to tell about my case as that might be helpful to somebody.

Given two entities: AdSet and AdSetPlacemnt. AdSet has the following property:

/**
* @ORM\OneToOne(targetEntity="AdSetPlacement", mappedBy="adSet", cascade={"persist"})
*
* @JMS\Expose
*/
protected $placement;

Then error appears when I try to delete some AdSet objects in a cycle after 1st iteration

foreach($adSetIds as $adSetId) {
/** @var AdSet $adSet */
$adSet = $this->adSetRepository->findOneBy(["id" => $adSetId]);


$this->em->remove($adSet);
$this->em->flush();
}

Error

A new entity was found through the relationship 'AppBundle\Entity\AdSetPlacement#adSet' that was not configured to cascade persist operations for entity: AppBundle\Entity\AdSet@00000000117d7c930000000054c81ae1. 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"}). If you cannot find out which entity causes the problem implement 'AppBundle\Entity\AdSet#__toString()' to get a clue.

Solution

The solution was to add "remove" to $placement cascade options to be: cascade={"persist","remove"}. This guarantees that Placement also becomes detached. Entity manager will "forget" about Placement object thinking of it as "removed" once AdSet is removed.


Bad alternative

When trying to figure out what's going on I've seen a couple answers or recommendations to simply use entity manager's clear method to completely clear persistence context.

foreach($adSetIds as $adSetId) {
/** @var AdSet $adSet */
$adSet = $this->adSetRepository->findOneBy(["id" => $adSetId]);


$this->em->remove($adSet);
$this->em->flush();


$this->em->clear();
}

So that code also works, the issue gets solved but it's not always what you really wanna do. Indeed it's happens quite rarely that you actually need to clear entity manager.