Doctrine2 - @OneToOne unidirectional object returns error save cascade

I have the following class:

/**
* @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
}

      

The Customer object is not my class, so I want this relationship to be unidirectional and not care what the customer looks like (minus the field id

).

Now from Doctrine Documentation I ended up not needing any other cascade={"persist"}

thing like in the error I am getting:

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.'

      

what am I doing wrong? And how can I fix this error?

PS: I don't want to change or save any information in this client, just to have a reference to the object.

LE: Because of this information Doctrine Documentation: cascade-persist I will output also some code from which the error is thrown. As the documentation says:

New entities in a collection not marked as cascade: persist will produce an Exception and rollback the flush() operation.

the error is caused by the next flush ()

$this->entityModel->persist($this->getDataInstance());
$this->entityModel->flush();

      

and the method getDataInstance

is a data object that has a Client, the client object is found from its repository using the findBy ('Customer', id) method. The Customer company is never updated or modified, so there is no need to save it.

getDataInstance

:

protected function getDataInstance()
{
    if (is_null($this->data)) {
        $this->initData();
    }
    return $this->data;
}

      

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

      

UPDATE: Still couldn't find an answer, but I did find some clues after talking to someone on the doctrine #IRC channel.

Here's the conversation:

p1: maybe your client object can be detached? for example de-serialization, using more than one object manager, or calling $ em-> clear () can lead to disconnection

p1: are you expecting to create a new customer? if not, then either you did it or you "found" an existing entity that would suggest one of the above

me: $ em-> clear () isn't being called by me for sure

me: de / serialization I'm not sure ... the store has an HTTP cache that can do this

p1: where do you get the object from? yes, the cache can do this if it caches clients not knowing about orm

me: and I am not expecting to create a new client, I just called one from the repository

me: $ customer = $ this-> swagModelManager-> getRepository ('Shopware \ Models \ Customer \ Customer') โ†’ findOneBy (['id' => $ this-> session-> sUserId]);

me: which returns zero or an object

p1: this is $ this, respectively $ this-> data cached between requests, perhaps?

me: findOneBy method can be found in EntityRepository.php (line 192)

me: hmm I don't know what never happens on my localhost and other installation, but on one client server it does: D and I assumed it has to do with caches and its settings on the server

me: so if this is a problem, how can I fix it?

me: not to trigger a cascading save

p1: The remote entity can be reconnected by doing "$ entity = $ em-> refresh ($ entity)" or "$ entity = $ em-> merge ($ entity)" (they differ in handling possible changes between entity state and db-refresh reloads data from db - "flushes", merge refreshes db) but this is not a fix, if you don't know why this is happening - you probably cannot tell when it is safe to do this

me: I know it's bad that I can't reproduce this - thanks for the advice!

p1: the main thing is that if EM says that it has found a "new" object and it already exists in the database, it is not "managed" by that EM - either it was disconnected in some way, or it is still attached, but to another instance of EM

me: then $ em-> refresh ($ entity) before saving should be enough, right? because I don't want to change anything related to this Entity

p1: you will need to do this with the specified client, so "$ entity-> client = $ em-> refresh ($ entity-> customer)" - but beware of the possible side effects of reassigning this (any events, side effects in the getter or the like things if you have)

Due to the fact that I cannot re-explain the error right now, I cannot say if the end of the conversation is the correct answer or not. When I will definitely know that I will revise the question / answer.

+3


source to share





All Articles