I encountered the problem of using the doctrine and realized that I was not fully aware of the mechanism of its work. I have several entities, the main one is the client (company, firm, team) this client has users, but all actions come from the client. It works fine everywhere, but I get an error with a certain transaction entity.
The client makes a transaction, then I get it and add to the payment. But when I write a transaction with the help of merge, flush, the transaction for some reason has a blank id null, although everything is written correctly to the database.

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(); } 

Here we have created a transaction and then I try to write it as payment.

  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(); } 

But the error takes off:

A new entity has been found through the relationship 'AppBundle \ Entity \ Payment' transaction.

It turns out that the doctrine has inserted into the database, but does not understand what it did, because it did not receive the transaction id and does not see it. Next, I tried to make persist transactions along the chain until the last User connection, when I make a persist on it, the doctrine tries to insert the user again into the database, although it is there.
Why in this case merge does not work, and persist does the user re-insert?

    1 answer 1

    From the presented example, the motives for using merge instead of persist are not clear, to answer in detail why the behavior described by you is observed, I need to know how the user object was received (apparently this one that is Client $client ) and how the Transaction $transaction object was obtained in the createPayment method. Why a new user is inserted when persist - I can assume that you created it through the new Client() , or took it from the cache, or something else, but somehow got it bypassing the EntityManager.

    To independently understand what is happening:

    1. Read the documentation describing how the merge () method works .

    2. Learn cascading operations in Doctrine. At one time, the answers to the questions Understanding Doctrine Cascade Operations and how to use them automatically helped to understand the essence of their work . , as well as the documentation section.

    You need to configure cascading operations in your objects and avoid using merge for new objects.

    • You are right, I, by my stupidity at logging on to the system, wrote down the essence of the client in the session so as not to tug him at each controller. So I couldn't use persist and used merge. And after I began to receive null and with merge, by giving up the idea of ​​sessions, all problems were eliminated. - Valentine Murnik