Qbrain
Qbrain

Reputation: 13

How can I solve duplicated entries in Many-To-One relations in Doctrine?

In one of our products, we are currently experiencing some issues regarding a many-to-one relation. The situation is as follows:

The problem with our current setup is that when we insert new likes, every single like gets a new liketype with the same string value as others, while I want them to be the same ID.

More visual, this is the current table showing our likes. It has a like_type_id containing the reference to the like type.

The table with likes

This is the table we have for the like types. As you can see, it generates 2 different liketypes with a different id and links them to the like.

The table with liketypes

My preferred situation is that whenever I persist a new like, Doctrine checks to see if the liketype already exists, and if so, links the already existing liketype id to the like. So that there is only 1 'media' liketype, and both likes have the same like_type_id.

Here is the xml configuration of my Like ORM Entity:

<doctrine-mapping xmlns="http://doctrine-project.org/schemas/orm/doctrine-mapping"
                  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                  xsi:schemaLocation="http://doctrine-project.org/schemas/orm/doctrine-mapping
                          https://www.doctrine-project.org/schemas/orm/doctrine-mapping.xsd">

    <entity name="MyNamespace\Like\Domain\Entity\Like" table="likes" repository-class="MyNamespace\Like\Infrastructure\Repository\LikeRepository">
        <id name="id" type="integer" column="id" length="191">
            <generator strategy="AUTO" />
        </id>

        <field name="userId" type="string" length="191" />

        <many-to-one field="likeType" target-entity="MyNameSpace\Like\Domain\Entity\LikeType" fetch="EAGER">
            <cascade>
                <cascade-persist/>
                <cascade-merge/>
            </cascade>
        </many-to-one>

        <field name="likedObjectId" type="string" length="191" />

    </entity>
</doctrine-mapping>

And this is the xml configuration of the like type:

<doctrine-mapping xmlns="http://doctrine-project.org/schemas/orm/doctrine-mapping"
                  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                  xsi:schemaLocation="http://doctrine-project.org/schemas/orm/doctrine-mapping
                          https://www.doctrine-project.org/schemas/orm/doctrine-mapping.xsd">

    <entity name="MyNameSpace\Like\Domain\Entity\LikeType" repository-class="MyNameSpace\Like\Infrastructure\Repository\LikeRepository">
        <id name="id" type="string" length="191">
            <generator strategy="AUTO" />
        </id>

        <field name="type" type="string" length="191" />
    </entity>
</doctrine-mapping>

Maybe we are making a simple mistake, but I could not find the solution to this problem, and while we have seen some workarounds by checking the database for an existing liketype, and then inserting the ID before persisting, we feel that it should be the task of the ORM to do this for us. So, I am wondering if there are some configuration mistakes we make in order to achieve this.

Thanks in advance.

-Danny Eerens

Upvotes: 1

Views: 56

Answers (1)

Cid
Cid

Reputation: 15257

Make the like_type.type field unique, it will prevent the inserting of duplicated values :

<field name="type" type="string" length="191" unique="true" />

And then, when you want to insert a new like, you can check if the type already exists :

// This is the name of the like_type --------------------------------------------------------------------v-----------v
if (($LikeType = $entityManager->getRepository('MyNameSpace\Like\Domain\Entity\LikeType')->findOneByName($likeTypeName)) == null)
{
    // the Like type wasn't found, create a new one
    $LikeType = new LikeType();
    $LikeType->setType($likeTypeName);
    $entityManager->persist($LikeType);
}
// Whatever if the like type is a new one or not, it can now be set to the like
$Like->SetLikeType($LikeType);
$entityManager->persist($Like);

Upvotes: 1

Related Questions