2
\$\begingroup\$

I managed to make a many to many relationship work correctly using mysql, doctrine 2 and symfony 3.4.

When a new element A that contains 0 to m element Bs is inserted, the B elements that already have the same content are reused, instead of creating new ones.

This is not the default doctrine 2 behaviour in a ManyToMany context with cascade={"persist", "remove"}.


The relationship uses an intermediate / join table, that contains id of table A and id of table B.

What I did is after deserializing the element A that contains m B elements, I check for each element B if a similar already exist in database.

If yes, I reuse it, if not I let doctrine cascade persist / insert new elements B.

Pseudocode, inside element A repository.

function useExistingDatabaseElementsBForNewElementA($elementA) {
    $elementsBs = $elementA->getElementsBs()
    // use existing elements B if available in database
    foreach ($elementsBs as $B) {

        /** @var B $matchingB*/
        $matchingB= $this->elementBRepository->findOneBy(['data' => $B->getData()]);

        if ($matchingB) {
            $elementA->removeElementB($B);
            $elementA->addElementB($matchingB);
        }
    }
}

I do this in the element A repository, by calling the findOne method of the element B repository and checking the result.

Is this is an acceptable / correct design choice / implementation.

How can it be better, for example using doctrine 2 configuration / annotations instead of my custom method in the element A repository ?

Could it be cleaner to implement it elsewhere or another way ?

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.