Querying Join Table in Doctrine

2019-04-29 15:27发布

I have the following two classes which are have a ManyToMany relationship and saved in a joining table called countries_involved.

class CountriesInvolved
{
/**
 * @var integer
 */
private $id;

/**
 * @var string
 */
private $description;

/**
 * @var \DateTime
 */
private $createdAt;

/**
 * @var \DateTime
 */
private $updatedAt;

/**
 * @var \ACME\SouthBundle\Entity\Country
 */
private $country;

/**
 * @var \Doctrine\Common\Collections\Collection
 */
private $involvement;
}

and

class Involvement
{
/**
 * @var integer
 */
private $id;

/**
 * @var string
 */
private $name;

/**
 * @var string
 */
private $description;
}

The relationship is defined as below in YML

manyToMany:
    involvement:
        targetEntity:   Involvement
        joinTable:
            name: countries_involvement
            joinColumns:
                case_country_involved_id:
                    referencedColumnName:   id
            inverseJoinColumns:
                involvement_id:
                    referencedColumnName:   id

I'm trying to return results of countries involved based on the id of an involvement but kind of stuck in writing the query without getting an error. Here's what I tried thus far:

$em = $this->getDoctrine()->getManager()->createQueryBuilder();
    $q = $em->select('c')
    ->from('ACMESouthBundle:CountriesInvolved','c')
    ->innerJOIN('c.Involvement','i')
    ->where('i.id = 1') 
    ->groupBy('c.country')->getQuery();

The error is:

[Semantical Error] line 0, col 80 near 'i WHERE i.id': Error: Class ACME\SouthBundle\Entity\CountriesInvolved has no association named Involvement

1条回答
相关推荐>>
2楼-- · 2019-04-29 16:06

Firstly, I would recommend the use of annotations, your code will be more readable.

The problem I think is that you have forgotten inversedBy and mappedBy properties.

The following code is a possible solution to your problem using annotations.

You should add this code to Involvement entity:

/**
 * @ORM\ManyToMany(targetEntity="CountriesInvolved", inversedBy="involvement")
 * @ORM\JoinTable(name="countries_involvement",
 *      joinColumns={@ORM\JoinColumn(name="case_country_involved_id", referencedColumnName="id")},
 *      inverseJoinColumns={@ORM\JoinColumn(name="involvement_id", referencedColumnName="id")}
 *      )
 */
 private $countries;

and in CountriesInvolved entity you should add the following annotations in $involvement:

/**
 * @ORM\ManyToMany(targetEntity="Involvement", mappedBy="countries")
 */
 private $involvement;

I have just rewrite the query, something like this:

$em = $this->getEntityManager();

$query = $em->createQuery('
    SELECT c
    FROM ACMESouthBundle:CountriesInvolved c
    JOIN c.involvement i
    WHERE i.id = :id
');

$query->setParameter('id', '1');

return $query->getResult();

EDIT

This is with YAML method:

CountriesInvolved:
    manyToMany:
        involvement:
            targetEntity: Involvement
            mappedBy: countries

CountriesInvolved:
    manyToMany:
        countries:
            targetEntity: CountriesInvolved
            inversedBy: involvement
            joinTable:
                name: countries_involvement
                joinColumns:
                    case_country_involved_id:
                        referencedColumnName: id
                inverseJoinColumns:
                    involvement_id:
                        referencedColumnName: id
查看更多
登录 后发表回答