我有以下课程:
/**
* @ORM\Entity(repositoryClass="Repository")
* @ORM\Table(name="my_data")
* @ORM\HasLifecycleCallbacks
*/
class Data extends ModelEntity
{
/**
* @var integer $id
*
* @ORM\Id
* @ORM\Column(type="integer")
* @ORM\GeneratedValue(strategy="IDENTITY")
*/
private $id;
/**
* @var Customer $userId
*
* @ORM\OneToOne(targetEntity="\Shopware\Models\Customer\Customer")
* @ORM\JoinColumn(name="userId", referencedColumnName="id")
*/
private $userId;
//in the class are more methods + getters and setters @not important
}
客户实体不属于我的类别,因此我希望这种关系是单向的,并且不关心客户的样子(减去id
字段)。
现在来自Doctrine documentation我知道我在错误中不需要任何其他cascade={"persist"}
内容:
exception 'Doctrine\ORM\ORMInvalidArgumentException' with message
'A new entity was found through the relationship
'Data#userId' that was not configured to cascade persist operations
for entity:
Shopware\Models\Customer\Customer@0000000035d66eab000000001b1ed901.
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
'Shopware\Models\Customer\Customer#__toString()' to get a clue.'
我做错了什么?我该如何解决这个错误?
PS:我不想修改或保存此客户中的任何信息,只是为了引用该实体。
LE:由于此信息Doctrine documentation: cascade-persist我还会输出一些来自错误触发的代码。正如文档中所述:
New entities in a collection not marked as cascade: persist will produce an Exception and rollback the flush() operation.
错误由以下 flush()
表达$this->entityModel->persist($this->getDataInstance());
$this->entityModel->flush();
并且getDataInstance
方法是具有客户的 Data 实体,通过方法从其存储库中找到 Customer 对象 findBy(' Customer',id)。 Customer 实体从未进行新的实例化或修改,因此无需持久化。
getDataInstance
:
protected function getDataInstance()
{
if (is_null($this->data)) {
$this->initData();
}
return $this->data;
}
和initData
:
private function initData()
{
if (is_null($this->data)) {
$this->data = new Data();
/**
* @var \Shopware\Models\Customer\Customer $customer
*/
$customer = $this->entityModel->getRepository('Shopware\Models\Customer\Customer')->findOneBy(['id' => $this->session->sUserId]);
$this->data->setUserId($customer);
}
}
更新:仍然没有找到答案,但我在与#IRC学说的某个人谈话后找到了一些线索。
以下是对话:
p1:您的客户实体可能已经脱离了吗?例如de / serialization,使用多个实体管理器或调用$ em-> clear()可能导致分离
p1:你期望创造新客户吗?如果没有那么你做了,或者它发现"一个已经存在的实体,它会建议上述之一我:$ em-> clear()不是我肯定打来的
me:de / serialization我不确定......商店有一个可以做到这一点的HTTP缓存
p1:你从哪里获得实体?是的,如果缓存在不知道orm的情况下缓存客户,缓存可能会这样做
我:我不希望创建一个新客户,我只是从存储库中调用了一个
me:$ customer = $ this-> swagModelManager-> getRepository(' Shopware \ Models \ Customer \ Customer') - > findOneBy([' id' => ; $ this-> session-> sUserId]);
me:重新启动null或对象
p1:是$ this,分别是$ this->可能在请求之间缓存的数据?
me:方法findOneBy可以在EntityRepository.php中找到(第192行)
我:嗯,我不知道,这件事是在我的本地主机和其他安装上从未发生过,但在1台客户端服务器上它确实:D和我认为这与缓存和他的设置有关在服务器上
我:如果这就是问题,我该如何解决?
我:不要将级联称为
p1:可以通过执行" $ entity = $ em-> refresh($ entity)"来重新附加分离的实体。或" $ entity = $ em->合并($ entity)" (它们在处理实体状态和数据库之间可能发生的变化方面有所不同 - 刷新从数据库重新加载数据 - "重置",合并更新数据库) - 但如果您不知道为什么这不是解决方法它发生了 - 你可能无法告诉它何时安全?
我:我知道,我不能重现这一点 - 感谢您的提示!
p1:主要的事情 - 如果EM说它发现" new"实体并且它已经存在于数据库中,它不是“管理”的。通过那个EM - 或者它已经以某种方式分离,或者它仍然被附加到一个不同的EM实例me:然后在持久化之前应该使用$ em->刷新($ entity),对吗?因为我不想改变与此实体相关的任何内容
p1:您必须对引用的客户执行此操作,因此" $ entity-> customer = $ em-> refresh($ entity-> customer)" - 但要注意重新分配的可能副作用(任何事件,吸气剂中的副作用或类似的东西,如果你有的话)
由于我现在无法重新定义错误,我不能说对话的结束是否是正确的答案。当我肯定知道我会修改问题/答案时。