Symfony 条令-通过关系找到一个新实体
自2周以来,我们在尝试刷新新元素时遇到了以下问题: 关键:条令\ORM\orInvalidargumentException: 通过关系“Comment#capture”找到了一个新实体,该关系未配置为级联实体的持久化操作 但是Symfony 条令-通过关系找到一个新实体,symfony,doctrine,Symfony,Doctrine,自2周以来,我们在尝试刷新新元素时遇到了以下问题: 关键:条令\ORM\orInvalidargumentException: 通过关系“Comment#capture”找到了一个新实体,该关系未配置为级联实体的持久化操作 但是capture已经在数据库中,我们通过findOneBy获取它,所以如果我们级联持久化它,或者持久化它,我们会得到一个 表约束冲突:重复条目 注释是在一个循环中创建的,其中包含不同的捕获,并设置了一个新的、所有必需的字段 当所有实体都被保存和/或通过findOne(且所有
capture
已经在数据库中,我们通过findOneBy
获取它,所以如果我们级联持久化它,或者持久化它,我们会得到一个
表约束冲突:重复条目
注释是在一个循环中创建的,其中包含不同的捕获,并设置了一个新的、所有必需的字段
当所有实体都被保存和/或通过findOne
(且所有实体都有效)获取时,刷新仍然失败
我讨论这个问题已经有一段时间了,所以请帮助我首先,您应该更好地保护您的代码,我在您的实体和控制器中看到了3个不同的缩进-这很难阅读,并且不符合要求 您控制器的代码不完整,我们不知道从哪里来
$this->activeCapture
。里面有一个$people['capture']
,我猜它包含一个capture
对象。这是非常重要的
如果$people['Capture']
中的捕获是从另一个EntityManager(而不是$this->EntityManager
(我们同样不知道它来自何处)持久化/获取的,Doctrine2就不知道该对象已经持久化了
您应该确保对所有这些操作使用同一实例的条令实体管理器(在EM对象上使用spl\u object\u hash
,以确保它们是相同的实例)
您还可以告诉EntityManager如何处理捕获对象
// 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);
如果这没有帮助,您应该提供更多代码。错误:
“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;
就我而言,这是一个过早的决定
$this->entityManager->clear();
造成问题的原因。它也消失了,只做了一个明确的最近的对象,如
$this->entityManager->clear($capture);
我遇到了同样的问题,它是相同的
EntityManager
。我想插入一个与对象相关的ManyToOne
。我不想要一个级联
持久化
例如:
$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();
我在尝试添加新实体时也遇到了此错误 我的情况是,我试图保存实体,但不应该保存。实体关系已填充并试图保存(
User
hasChat
在许多情况下,但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();
我的答案与主题相关,但与您的具体情况不太相关,所以对于那些在谷歌上搜索的人,我发布了这篇文章,因为上面的答案对我没有帮助
在我的例子中,我对具有关系的批处理实体有相同的错误,并且该关系被设置为非常相同的实体
我做错了什么:
当我执行$this->entityManager->clear()时代码>在处理一批实体时,我会得到这个错误,因为下一批实体将指向分离的相关实体
出了什么问题:
我不知道$this->entityManager->clear()代码>的工作原理与$this->entityManager->detach($entity)相同代码>仅分离所有repositorie的实体
我认为$this->entityManager->clear()代码>还分离相关实体
我应该做什么:
我应该迭代实体并逐个分离它们——这不会分离未来实体指向的相关实体
我希望这对某人有所帮助。刷新相关实体有助于我的案例
/* $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
已经在别处设置了产品
(结果是通过EntityManager
的不同实例设置的),但我仍然收到了错误
这是一种黑客行为,通过检索现有产品的id
,然后检索它的引用,然后使用setProduct
来“刷新”连接。后来我通过确保代码中只有一个EntityManager
实例来修复它。向我们展示一些代码,例如控制器和实体。这是一个相关问题,可能会对您有所帮助:以下是来自控制器的代码:,以下是实体注释中的字段:同时访问条令是否可能会导致此错误?我还尝试使用自定义锁定原则,但没有附加任何内容…你的粘贴箱不再存在->除非绝对必要,否则不在帖子中使用链接是一个很好的理由。我尝试刷新我拥有的所有activeCapture实体,但什么都没有。。。我确信我只有一个EntityManager,因为我使用“get('doctrine.orm.default\u entity\u manager')”。$this->activeCapture在这里给出:getActiveCapture在这里给出:为什么要分离第36行的捕获?如果捕获在某个地方被引用,Doctrine不再知道任何关于它的信息,然后可以抛出您得到的异常类型。此过程允许我们刷新捕获实体,但此函数打印日志,不调用(不打印调试),我正在尝试删除它,对于提到必须是同一实体管理器实例的检查+1,merge会导致Doctrine找到具有相同ID的现有$product(我们称之为$originalProduct),并将$product与$originalProduct合并。请注意,这样做的副作用是$
/* $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();