学说 - 通过这种关系找到了一个新的实体

isu*_*dil 65 doctrine symfony

从2周开始,我们在尝试刷新新元素时遇到了这个问题:

CRITICAL:Doctrine\ORM\ORMInvalidArgumentException:

通过"Comment#capture"关系找到了一个新实体,该关系未配置为级联实体的持久操作

但是capture已经存在于数据库中,我们正在通过a获取它findOneBy,所以如果我们级联持续它,或者坚持它,我们得到一个

表约束违规:重复条目.

注释是在带有不同捕获的循环中创建的,并且设置了新的和所有必需字段.

由于所有实体都持久化和/或得到findOne(并且全部有效),因此刷新仍然失败.

我有一段时间在这个问题,所以请帮助我

Mir*_*vic 55

我有同样的问题,它是一样的EntityManager.我想插入一个相关的对象ManyToOne.我不想要一个cascade persist.

示例:

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

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

$em->persist($product);
$em->flush();
Run Code Online (Sandbox Code Playgroud)

这给我带来了同样的例外.

所以解决方案是:

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

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

$em->merge($product);
$em->flush();
Run Code Online (Sandbox Code Playgroud)

  • 合并导致Doctrine找到具有相同ID的现有$产品(让我们称之为$ originalProduct)并将$ product与$ originalProduct合并.请注意,这会产生副作用,即$ product的所有属性都将复制到$ originalProduct.来源:http://doctrine-orm.readthedocs.org/en/latest/reference/working-with-objects.html应用于实体X的合并操作的语义如下:如果X是分离的实体,X的状态被复制到具有相同标识的预先存在的被管实体实例X'上. (5认同)
  • 解决方案也适用于我,但我对此并不满意.我认为必定有一些我在某处(可能在某些配置文件中)做错了导致这种情况.我从未在另一个项目上遇到过这个问题. (5认同)
  • @FrancescoD.M.:我遇到了同样的问题,我首先用“_merge_”解决方案修复了它,但我和你有同样的不愉快感觉。所以我一直在寻找,终于找到了我的错误。我意识到导致问题的实体不是由我的实体经理管理的。事实上,它只是被反序列化了:它是完整的,当然包括 id,这让我产生了 Doctrine 意识到它的错觉。但事实并非如此。所以我只是要求序列化程序 (_jms_) 获取数据库中的实体(使用 _SubscribingHandlerInterface_),然后 _persist_ 成功了。希望这可以帮助。 (2认同)
  • 我花了一些时间,但就我而言,这是不同的 EM 实例。 (2认同)

own*_*ing 40

在我的情况下,太早的呼吁

$this->entityManager->clear();
Run Code Online (Sandbox Code Playgroud)

引起了这个问题.它只是通过对最近的对象做一个明确的消失而消失了

$this->entityManager->clear($capture);
Run Code Online (Sandbox Code Playgroud)

  • 参数不能是对象,而是类名 (2认同)

dra*_*nli 29

我的回答与主题相关,但与你的特定情况不太相关,所以对于那些谷歌搜索我发布这个,因为上面的答案没有帮助我.

就我而言,我对具有关系的批处理实体有同样的错误,并且该关系设置为同一个实体.

我错了什么:

当我$this->entityManager->clear();在处理批量实体时执行此操作时,我会收到此错误,因为下一批实体将指向已分离的相关实体.

什么地方出了错:

  1. 我不知道它的$this->entityManager->clear();作用是相同的,$this->entityManager->detach($entity);只是分离了所有的存储库实体.

  2. 我认为这$this->entityManager->clear();也会分离相关实体.

我应该做什么:

我应该迭代实体并逐个分离它们 - 这不会分离未来实体所指向的相关实体.

我希望这可以帮助别人.

  • @drakonli,你不必遍历每个实体来分离,你可以使用`$ this-> entityManager-> clear('EntityName');`只分离一种实体.如果分离的那些都是相同的类型并且在EM中不再需要,可能会有帮助 (2认同)

Dam*_*ien 9

首先,你应该更好地照顾你的代码,我看到你的实体和控制器中有3个不同的缩进 - 这很难阅读,并且不符合Symfony2编码标准.

为控制器显示的代码不完整,我们不知道$this->activeCapture从哪里来.在里面你有一个$people['capture']包含Capture我认为的对象.这是非常重要的.

如果Capture in $people['capture']从另一个EntityManager持久保存/获取$this->entityManager(同样,我们不知道它来自何处),Doctrine2不知道该对象已经存在.

您应确保对所有这些操作使用相同的Doctrine Entity Manager实例(spl_object_hash在EM对象上使用以确保它们是同一个实例).

您还可以告诉EntityManager如何处理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);
Run Code Online (Sandbox Code Playgroud)

如果这没有帮助,您应该提供更多代码.

  • 提及它必须是同一个实体管理器实例的+1 (8认同)

Den*_*nis 7

刷新有问题的实体有助于我的案例。

/* $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();
Run Code Online (Sandbox Code Playgroud)

尽管我$item已经在Product其他地方设置了一个集合(结果它是通过 的不同实例设置的EntityManager),但我仍然收到错误消息。

所以这是一种 hack,通过检索id现有产品,然后检索它的引用,并使用setProduct“刷新”任何连接。后来我通过确保EntityManager在我的代码中只有一个实例来修复它。


小智 6

错误:'Comment#capture'未配置为级联实体的持久操作

问题:

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

不要配置级联持久化

试试这个:

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

  • 如果我不想级联持久化或删除怎么办? (3认同)