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


73

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

严重:Doctrine \ ORM \ ORMInvalidArgumentException:

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

但是,capture已经在数据库中,并且通过来获取它findOneBy,因此,如果我们级联对其进行持久化,或者对它进行持久化,我们将获得一个

违反表约束:重复输入。

注释是在具有不同捕获内容的循环中创建的,并带有新的注释,并设置了所有必填字段。

在所有实体都持久存在和/或由findOne(以及所有有效)获得的情况下,刷新仍然失败。

一段时间以来,我一直在处理此问题,所以请帮助我


3
给我们看一些代码,例如控制器和实体。
cheesemacfly

这是一个相关问题,可能会对您有所帮助:stackoverflow.com/questions/18171801/…– 2013
翻转

这是来自控制器的代码:pastebin.com/J0Keukfy,这是来自实体注释的字段:pastebin.com/nG4rE1Pp
isundil 2013年

同时访问该理论是否有可能引发此错误?我还尝试过使用自定义来锁定原则,但是没有附加任何内容……
isundil

6
您的信息仓不再存在->除非绝对必要,否则不使用帖子中的链接的充分理由。
手工艺者

Answers:


56

我有同样的问题,也一样EntityManager。我想插入一个与之相关的对象ManyToOne。而且我不想cascade persist

范例:

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

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

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

这为我抛出了同样的例外。

所以解决方案是:

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

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

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

5
合并会使Doctrine查找具有相同ID的现有$ product(将其称为$ originalProduct),然后将$ product与$ originalProduct合并。请注意,这样做的副作用是$ product的所有属性都将复制到$ originalProduct。来源:doctrine-orm.readthedocs.org/en/latest/reference/… 适用于实体X的合并操作的语义如下:如果X是一个分离的实体,则将X的状态复制到pre -具有相同标识的现有管理实体实例X'。
Rauni Lillemets 2015年

5
该解决方案也对我有用,但是我对此并不满意。我认为在某处(可能在某些配置文件中)我做错了某些事情,这会导致这种情况。我从来没有在另一个项目上遇到这个问题。
Francesco DM

2
@ FrancescoD.M .:我遇到了同样的问题,我首先使用“合并”解决方案解决了该问题,但是我和您有同样的不适感。所以我继续寻找,最后发现了我的错误。我意识到导致问题的实体不受我的实体经理管理。实际上,它只是反序列化的:它是完整的,当然还包括id,这使我产生了一种误解,即教义已意识到这一点。但事实并非如此。因此,我只是要求序列化器(jms)来获取数据库中的实体(使用SubscribingHandlerInterface),然后持久化成功。希望这可以帮助。
moudug

1
花了我一些时间,但就我而言,它是不同的EM实例。
GrumpyHat

工作正常,但只有在我摆脱了class 'VariablesGroup' does not exist错误之后。解决方案是使用班级的FQN,"App\Domain\VariablesGroup\VariablesGroup"而不是在$
em-

43

就我而言,还为时过早

$this->entityManager->clear();

造成了问题。它也仅通过清除最近的对象而消失,例如

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

1
这里也一样,但是我不明白是为什么clear()导致这种行为?
Bananaapple

2
参数应该不是对象,而是类名
Mindau

38

我的答案与主题相关,但与您的特定情况无关,因此对于那些谷歌搜索人员,我发布了此信息,因为上述答案对我没有帮助。

就我而言,我对具有关系的批处理实体存在相同的错误,并且该关系设置为完全相同的实体。

我错了什么:

当我$this->entityManager->clear();在处理一批实体时这样做时,会出现此错误,因为下一批实体将指向分离的相关实体。

什么地方出了错:

  1. 我不知道它的$this->entityManager->clear();工作原理与$this->entityManager->detach($entity);仅分离存储库的所有实体相同。

  2. 我以为那$this->entityManager->clear();也分离了相关实体。

我应该做的事情:

我应该遍历实体,然后将它们一个接一个地分离-那样就不会分离将来的实体所指向的相关实体。

我希望这可以帮助别人。


我永远不会自己找到它,很好的回答,谢谢!
Hammerbot

4
@drakonli,您不必遍历每个实体即可分离,您可以使用它$this->entityManager->clear('EntityName');来分离一种实体。如果要分离的组件属于同一类型并且在EM中不再需要,则可能会有所帮助
Sujan Adiga

9

首先,您应该更好地保护自己的代码,我发现您的实体和控制器中有3种不同的缩进方式-很难阅读,并且不符合Symfony2编码标准

为控制器显示的代码不完整,我们不知道$this->activeCapture从哪里来。在您的内部,$people['capture']其中包含一个Capture我假定的对象。这个非常重要。

如果Capture in$people['capture']是从另一个EntityManager持久化/获取的$this->entityManager(而不是从哪里来的),则Doctrine2不知道该对象已经持久化。

您应确保对所有这些操作使用“ Doctrine实体管理器”的相同实例(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);

如果这样做没有帮助,则应提供更多代码。


我试图刷新我拥有的所有activeCapture实体,但是什么也没有。我确定我只有一个EntityManager,因为我使用的是“ get('doctrine.orm.default_entity_manager')”。$ this-> activeCapture在此处给出:pastebin.com/px0cyWs0和getActiveCapture在此处:pastebin.com/D0LRW2TD
isundil 2013年

为什么要分离pastebin.com/px0cyWs0的Captures第36行?如果捕获是在某个地方引用的,Doctrine对此将一无所知,然后会抛出您遇到的异常。
Damien

此过程使我们可以刷新捕获实体,但是此函数会打印日志,并且不会调用(未打印调试)
isundil 2013年

我正在尝试将其删除,以进行检查
isundil 2013年

8
+1,因为它必须是同一实体管理器实例
kdazzle 2013年

6

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

问题:

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

不要配置级联持续

试试这个:

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

1
如果我不想级联保留或删除该怎么办?
user3890355

4

刷新有关实体有助于我的案件。

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

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

因此,通过检索id现有产品,然后检索其引用,并使用setProduct“刷新”任何连接,这是种黑客行为。后来,我通过确保EntityManager代码中只有一个实例来修复它。


0

尝试添加新实体时,我也收到此错误。

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

我的情况是我尝试保存实体,不应保存该实体。实体关系被填充并试图保存(在Many2Many中User具有Chat,但是Chat是一个临时实体),但是存在一些冲突。

因此,如果我使用该程序,cascade={"persist"}则会发生不良行为-保存垃圾箱实体。我的解决方案是从所有保存实体中删除非保存实体:

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

保存代码

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

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

嘿,您已经提到实体存在于数据库中,因此您的答案对这个问题没有任何意义。
vivex

@Vivek好吧,我通过google找到了该页面,这与我得到的错误最相关,所以我不得不自己寻找解决方案,最后我把它留在这里,以帮助其他遇到相同错误的人。如果您不方便我很抱歉。
shukshin.ivan,2015年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.