Doctrine “has no association named”

2019-07-28 08:43发布

问题:

Add me to the list of people who can't work out what's wrong with their Doctrine mapping. I'm modelling a Chess Game with OneToMany Halfmoves - any ideas?

DDL:

create table game ( game_id int primary key  ); 
create table halfmove(halfmove_id int primary key, game_id int);

Game.php:

/**
* Game
*
* @ORM\Table(name="game")
* @ORM\Entity
*/
class Game  
{
/**
 * @ORM\OneToMany(targetEntity="Halfmove", mappedBy="game")
 */
private $halfmoves;

public function getHalfmoves(){
    return $this->halfmoves;
}

public function setHalfmoves($halfmoves){
    $this->$halfmoves = $halfmoves;
}

public function __construct()
{
    $this->halfmoves = new ArrayCollection();
}
...

Halfmove.php:

/**
 * Halfmove
 *
 * @ORM\Table(name="halfmove")
 * @ORM\Entity
 */
class Halfmove
{
/**
 * @var integer
 *
 * @ORM\Column(name="game_id", type="integer", nullable=true)
 */
private $gameId;


/**
 * @ORM\ManyToOne(targetEntity="Game", inversedBy="halfmoves")
 * @ORM\JoinColumn(name="game_id", referencedColumnName="game_id")
 */
private $game;

public function getGame(){
    return $this->game;
}

public function setGame($game){
    $this->game = $game;
}
...

Query that generates error:

    $em = $this->getDoctrine()->getManager();
    $query = $em
    ->createQuery(
            'SELECT p, c FROM AppBundle:Halfmove p
        JOIN p.Game c
        WHERE c.game_id = :id'
            )->setParameter('id', 3525);
    $result =  $query->getSingleResult();

Error message:

2016-11-28 12:46:46] request.CRITICAL: Uncaught PHP Exception Doctrine\ORM\Query\QueryException: "[Semantical Error] line 0, col 62 near 'c ': Error: Class AppBundle\Entity\Halfmove has no association named Game" at /Users/cats/Sites/chess-ui/vendor/doctrine/orm/lib/Doctrine/ORM/Query/QueryException.php line 63 {"exception":"[object] (Doctrine\ORM\Query\QueryException(code: 0): [Semantical Error] line 0, col 62 near 'c\n ': Error: Class AppBundle\Entity\Halfmove has no association named Game at /Users/cats/Sites/chess-ui/vendor/doctrine/orm/lib/Doctrine/ORM/Query/QueryException.php:63, Doctrine\ORM\Query\QueryException(code: 0): SELECT p, c FROM AppBundle:Halfmove p\n JOIN p.Game c\n WHERE c.game_id = :id at /Users/cats/Sites/chess-ui/vendor/doctrine/orm/lib/Doctrine/ORM/Query/QueryException.php:41)"} []

回答1:

You declared $game in Halfmove entity. Try after replacing p.Game with p.game.

$em = $this->getDoctrine()->getManager();
$query = $em->createQuery(
        'SELECT p, c FROM AppBundle:Halfmove p
            JOIN p.game c
            WHERE c.game_id = :id'
        )->setParameter('id', 3525);
$result =  $query->getSingleResult();

Additional Update

Additionally i recommend some changes in you entities.

Game.php

<?php

use Doctrine\ORM\Mapping as ORM;

/**
* Game
*
* @ORM\Table(name="game")
* @ORM\Entity
*/
class Game  
{

    /**
     * @var integer
     *
     * @ORM\Column(name="id", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    protected $id;

    /**
     * @ORM\OneToMany(targetEntity="Halfmove", mappedBy="game")
     */
    private $halfmoves;

    public function getHalfmoves(){
        return $this->halfmoves;
    }

    public function setHalfmoves($halfmoves){
        $this->$halfmoves = $halfmoves;
    }

    public function __construct()
    {
        $this->halfmoves = new ArrayCollection();
    }
    ...

Halfmove.php

<?php
use Doctrine\ORM\Mapping as ORM;

/**
 * Halfmove
 *
 * @ORM\Table(name="halfmove")
 * @ORM\Entity
 */
class Halfmove
{
    /**
     * @var integer
     *
     * @ORM\Column(name="id", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    protected $id;

    /**
     * @ORM\ManyToOne(targetEntity="Game", inversedBy="halfmoves")
     * @ORM\JoinColumn(name="game_id", referencedColumnName="id")
     */
    private $game;

    public function getGame(){
        return $this->game;
    }

    public function setGame($game){
        $this->game = $game;
    }
    ...

Execute Query

$query = $em->getRepository("Halfmove")
    ->createQueryBuilder('p')
    ->innerJoin("p.game", 'c')
    ->where("c.id = :CId")
    ->setParameter("CId", 3525);

$moves = $query->getQuery()->getResult();


回答2:

Try this one :

/**
 * @ORM\ManyToOne(targetEntity="Game", inversedBy="halfmoves")
 * @ORM\JoinColumn(name="game_id", referencedColumnName="id")
 */
private $game;

Change game_id to id in referencedColumnName.



回答3:

the problem in my case was that Mapping information was not coming from the entity Annotations at all - it was being read from the Xml mappings that were created as part of the reverse engineering (from DB) process. Once these were deleted, the Annotations were used and everything worked as expected.