Dirkos
Dirkos

Reputation: 676

Doctrine ORM ManyToMany is missing field data

I am upgrading my old PHP7 app to PHP8.1 and found out that i have some weird mapping issue with Doctrine module (which is a Laminas integration of ORM). With the upgrade i switched from the annotations driver to the atribute driver but due a weird reason my ManyToMany relation is giving an error:

A subset of my classes are here:

<?php
#[ORM\Entity]
#[ORM\Table(name: 'ScoreScale')]
class ScoreScale
{
    #[ORM\Id]
    #[ORM\GeneratedValue(strategy: 'AUTO')]
    #[ORM\Column(type: 'integer', name: 'scoreScaleId')]
    private $id;

    #[ORM\ManyToMany(targetEntity: Qualification::class, inversedBy: 'scoreScaleCollection')]
    #[ORM\JoinTable(
        name: 'scorescale_qualification',
        joinColumns: [new ORM\JoinColumn(name: 'scoreScaleId', referencedColumnName: 'scoreScaleId')],
        inverseJoinColumns: [new ORM\JoinColumn(name: 'qualificationId', referencedColumnName: 'qualificationId')]
    )]
    private $qualificationCollection;
}
?>

<?php
#[ORM\Entity(repositoryClass: QualificationRepository::class)]
#[ORM\Table(name: 'Qualification')]
class Qualification implements JsonSerializable, Stringable
{
    #[ORM\Id]
    #[ORM\GeneratedValue(strategy: 'AUTO')]
    #[ORM\Column(type: 'integer', name: 'qualificationId')]
    private $id;

    #[ORM\ManyToMany(targetEntity: ScoreScale::class, mappedBy: 'qualificationCollection')]
    private $scoreScaleCollection;
}

The problem there actually is, is the ManyToMany on the ScoreScale class. The error that i am actually getting when validating the schema integrity is:

 [FAIL] The entity-class Result\Entity\ScoreScale mapping is invalid:
 * The referenced column name 'id' has to be a primary key column on the target entity class 'Result\Entity\ScoreScale'.
 * The referenced column name 'id' has to be a primary key column on the target entity class 'Qualification\Entity\Qualification'.

The weird thing is that there is no reference column id even listed in my mappings. When I dive a little deeper in the validator itself and I dump the actual data that is causing this it seems my mapping is not there as defined. The joinColumns and the inverseJoinColumns are different somehow?

Array
(
    [fieldName] => qualificationCollection
    [joinTable] => Array
        (
            [name] => scorescale_qualification
            [schema] => 
            [joinColumns] => Array
                (
                    [0] => Array
                        (
                            [name] => id
                            [referencedColumnName] => id
                            [onDelete] => CASCADE
                        )

                )

            [inverseJoinColumns] => Array
                (
                    [0] => Array
                        (
                            [name] => id
                            [referencedColumnName] => id
                            [onDelete] => CASCADE
                        )

                )

        )

Somehow I do think it could be a bug in the mapping but I am not 100% sure. Hope that someone has an idea.

Best, Pim

Upvotes: 0

Views: 608

Answers (1)

YTZ
YTZ

Reputation: 938

The syntax you're using for JoinTable in the ScoreScale entity seems to be a combination of annotations and attributes.

This PR in the doctrine/orm repo states the following:

Instead of @JoinTable holding join columns and inverse join columns as a property, you use #[ORM\JoinColumn] and #[ORM\InverseJoinColumn] on the top level.

The documentation shows an example on how to use attributes for a many-to-many relation.

So for your example the correct syntax should be:

#[ORM\ManyToMany(targetEntity: Qualification::class, inversedBy: "scoreScaleCollection")]
#[ORM\JoinTable(name: "scorescale_qualification")]
#[ORM\JoinColumn(name: "scoreScaleId", referencedColumnName: "scoreScaleId")]
#[ORM\InverseJoinColumn(name: "qualificationId", referencedColumnName: "qualificationId")]
private $qualificationCollection;

Upvotes: 1

Related Questions