我遇到了使用该学说的问题,意识到我没有完全理解它的工作机制。我有几个实体,主要的是客户(公司、公司、团队),这个客户有用户,但所有的动作都来自客户。它在任何地方都可以正常工作,但是对于某个交易实体,我会出错。
客户进行交易,然后我收到它并将其添加到付款中。但是,当我使用 merge、flush 编写事务时,由于某种原因事务有一个空的 id null,尽管所有内容都已正确写入数据库。
public function createConfirmedTransaction(Client $client, PaymentMethod $method, $amount, $wallet, $invoice, $payment_code)
{
$status = $this->getStatus('confirmed');
$transaction = new Transaction();
$transaction->setClient($client);
$transaction->setMethod($method);
$transaction->setAmount($amount);
$transaction->setWallet($wallet);
$transaction->setInvoice($invoice);
$transaction->setPaymentCode($payment_code);
$transaction->setStatus($status);
$transaction->setConfirmedAt(new \DateTime());
$this->entityManager->merge($transaction);
$this->entityManager->flush();
return $transaction->getId();
}
在这里,我们创建了一个交易,然后我尝试将其记录为付款。
public function createPayment(Client $client, PaymentMethod $method, Transaction $transaction, $usd)
{
$payment = new Payment();
$payment->setTransaction($transaction);
$payment->setClient($client);
$payment->setMethod($method);
$payment->setAmount($usd);
$this->entityManager->merge($payment);
$this->entityManager->flush();
}
但是会抛出一个错误:
通过关系“AppBundle\Entity\Payment#transaction”找到了一个新实体,该实体未配置为级联实体的持久操作。
事实证明,主义对数据库进行了插入,但不理解它做了什么,因为它没有收到事务 id,也没有看到它。接下来,我尝试沿着链进行持久事务,直到最后一个用户连接,当我坚持它时,该学说试图再次将用户插入数据库,尽管它在那里。
为什么在这种情况下合并不起作用并且坚持用户重新插入?
从给出的示例来看,广泛使用 merge 而不是 persist的动机尚不清楚,为了详细回答为什么观察到您描述的行为,我需要知道用户对象是如何获得的(显然是这个
Client $client
)和如何Transaction $transaction
在createPayment
. 为什么在 persist 期间插入新用户 - 我可以假设您是通过创建它new Client()
,或者从缓存中获取它,或者以其他方式获取它,但以某种方式绕过了 EntityManager。要弄清楚发生了什么:
阅读描述 merge() 方法如何工作的文档。
在 Doctrine 中学习级联操作。有一次, Understanding Doctrine Cascade Operations和How to use the cascade option in Doctrine2 to have associated entities automatically persisted这两个问题的答案有助于理解他们工作的本质。,以及文档部分。
您应该在对象上设置级联操作,并避免在新对象上使用合并。