Doctrine2: OneToMany и JOIN, помогите разобраться...

d1gi

Новичок
Задача в принципе простая, есть 2 таблицы: Sites и SitesDomain
т.е. один и тотже сайт может откликаться на несколько доменов.

SQL:
CREATE TABLE `engine_sites` (
  `site_id` int(11) NOT NULL AUTO_INCREMENT,
  `properties` longtext NOT NULL COMMENT '(DC2Type:array)',
  `create_datetime` datetime NOT NULL,
  PRIMARY KEY (`site_id`)
) ENGINE=InnoDB;

CREATE TABLE `engine_sites_domains` (
  `domain` varchar(255) NOT NULL,
  `site_id` int(11) NOT NULL,
  PRIMARY KEY (`domain`),
  KEY `site_id` (`site_id`)
) ENGINE=InnoDB;
Мне нужно получить сайт запросив его домен, например раньше я делал так:

SQL:
SELECT s.*
FROM engine_sites AS s
JOIN engine_sites_domains AS d ON s.site_id = d.site_id
WHERE d.domain = 'localhost'
Сейчас пытаюсь всё это перевести на ОРМ, создал 2 класса сущностей:

PHP:
<?php
namespace SmartCore\Bundle\EngineBundle\Entity;

use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\ArrayCollection;
use SmartCore\Bundle\EngineBundle\Entity\SiteDomains;

/**
 * @ORM\Entity
 * @ORM\Table(name="engine_sites")
 */
class Site
{
    /**
     * @ORM\Id
     * @ORM\Column(type="integer")
     * @ORM\GeneratedValue(strategy="AUTO")
     * 
     * @ORM\OneToMany(targetEntity="SiteDomains", mappedBy="site_id")
     * @ORM\JoinColumn(name="site_id", referencedColumnName="site_id")
     */
    protected $site_id;

    /**
     * @ORM\Column(type="array")
     */
    protected $properties;

    /**
     * @ORM\Column(type="datetime")
     */
    protected $create_datetime;
    
    public function __construct()
    {
        $this->create_datetime = new \DateTime();
        $this->properties = new ArrayCollection();
    }
}
PHP:
<?php
namespace SmartCore\Bundle\EngineBundle\Entity;

use Doctrine\ORM\Mapping as ORM;
use SmartCore\Bundle\EngineBundle\Entity\Site;

/**
 * @ORM\Entity
 * @ORM\Table(name="engine_sites_domains",
 *      indexes={
 *          @ORM\Index(name="site_id", columns={"site_id"})
 *      }
 * )
 */
class SiteDomains
{
    /**
     * @ORM\Id
     * @ORM\Column(type="string")
     */
    protected $domain;

    /**
     * @ORM\Column(type="integer")
     * 
     * @ORM\ManyToOne(targetEntity="Site", inversedBy="site_id")
     * @ORM\JoinColumn(name="site_id", referencedColumnName="site_id")
     */
    protected $site_id;
}
Далее написал DQL:
SQL:
SELECT s
FROM SmartCoreEngineBundle:Site s JOIN s.site_id d
WHERE d.domain = 'localhost'
в ответ получаю ошибку:

Код:
[Semantical Error] line 0, col 71 near 'd
': Error: Class SmartCore\Bundle\EngineBundle\Entity\Site has no association named site_id
Читал http://docs.doctrine-project.org/projects/doctrine-orm/en/2.1/reference/association-mapping.html
http://odiszapc.ru/doctrine/association-mapping/
http://docs.doctrine-project.org/en/latest/reference/dql-doctrine-query-language.html
но чувствую, что-то где-то непонял :(

Скорее всего неправильно определил связи... но крутил уже всяко разно... а может быть и сам DQL неверно составлен :( кеш симфони очищаю постоянно, в доктрине кеш тоже отключен...

Если кто увидел явно ошибку, ткните пальцем плиз? :)
 

d1gi

Новичок
Добавил коллекцию siteDomains

PHP:
<?php
namespace SmartCore\Bundle\EngineBundle\Entity;

use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\ArrayCollection;
use SmartCore\Bundle\EngineBundle\Entity\SiteDomains;

/**
 * @ORM\Entity
 * @ORM\Table(name="engine_sites")
 */
class Site
{
    /**
     * @ORM\Id
     * @ORM\Column(type="integer")
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    protected $site_id;
    
    /**
     * @ORM\Column(type="array")
     */
    protected $properties;

    /**
     * @ORM\Column(type="datetime")
     */
    protected $create_datetime;
    
    /**
     * @ORM\OneToMany(targetEntity="SiteDomains", mappedBy="site_id")
     * @ORM\JoinColumn(name="site_id", referencedColumnName="site_id")
     */
    protected $siteDomains;
    
    public function __construct()
    {
        $this->create_datetime = new \DateTime();
        $this->properties = new ArrayCollection();
        $this->siteDomains = new ArrayCollection();
    }
    
    public function getId()
    {
        return $this->site_id;
    }
    
    public function getSiteId()
    {
        return $this->site_id;
    }  
}
Также немного изменился класс siteDomains

PHP:
<?php
namespace SmartCore\Bundle\EngineBundle\Entity;

use Doctrine\ORM\Mapping as ORM;
use SmartCore\Bundle\EngineBundle\Entity\Site;

/**
 * @ORM\Entity
 * @ORM\Table(name="engine_sites_domains",
 *      indexes={
 *          @ORM\Index(name="site_id", columns={"site_id"})
 *      }
 * )
 */
class SiteDomains
{
    /**
     * @ORM\Id
     * @ORM\Column(type="string")
     */
    protected $domain;

    /**
     * @ORM\Column(type="integer")
     * @ORM\ManyToOne(targetEntity="Site", inversedBy="site_id")
     * @ORM\JoinColumn(name="site_id", referencedColumnName="site_id")
     */
    protected $site_id;
    
    /**
     * @ORM\Column(type="datetime")
     */
    protected $create_datetime;
    
    public function __construct()
    {
        $this->create_datetime = new \DateTime();
    }     
}
при выполнении php app/console doctrine:schema:validate, получаю в ответ:

Код:
$ php app/console doctrine:schema:validate
[Mapping]  FAIL - The entity-class 'SmartCore\Bundle\EngineBundle\Entity\Site' mapping is invalid:
* The association SmartCore\Bundle\EngineBundle\Entity\Site#siteDomains refers to the owning side field SmartCore\Bundle\EngineBundle\Entity\SiteDomains#site_id which is not defined as association.
* The association SmartCore\Bundle\EngineBundle\Entity\Site#siteDomains refers to the owning side field SmartCore\Bundle\EngineBundle\Entity\SiteDomains#site_id which does not exist.
Так и не могу понять как можно решить данную задачу :(
 
Сверху