Symfony2,doctrine ManyToOne关系错误

时间:2013-04-24 16:30:22

标签: symfony doctrine-orm

我正在尝试使用Symfony2和Doctrine构建在某些站点上执行的某些操作的日志。我有2个表站点和日志。 Logs表将包含一个siteid,它是sites表的id列的外键。 Logs表可以为同一站点提供多个日志。

当我尝试在日志表中插入一个条目时,我得到siteid为空错误。

这是我的代码:

网站实体:

<?php

namespace A\SHB\Entity;

use Doctrine\ORM\Mapping as ORM;

/**
 * Sites
 *
 * @ORM\Table()
 * @ORM\Entity(repositoryClass="A\SHB\Entity\SitesRepository")
 */
class Sites
{
    /**
     * @var integer
     *
     * @ORM\Column(name="id", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $id;

    /**
     * @var ArrayCollection $siteLog
     *
     * @ORM\OneToMany(targetEntity="Logs", mappedBy="log", cascade={"persist"})
     * @ORM\OrderBy({"siteid" = "ASC"})
     * @ORM\JoinColumns({
     *   @ORM\JoinColumn(name="log_id", referencedColumnName="siteid")
     * })
     */
    private $siteLog;

    /**
     * Get id
     *
     * @return integer 
     */
    public function getId()
    {
        return $this->id;
    }

    /**
     * Constructor
     */
    public function __construct()
    {
        $this->siteLog = new \Doctrine\Common\Collections\ArrayCollection();
    }

    /**
     * Add siteLog
     *
     * @param \A\SHB\Entity\SiteLog $siteLog
     * @return Sites
     */
    public function addSiteLog(\A\SHB\Entity\SiteLog $siteLog)
    {
        $this->siteLog[] = $siteLog;

        return $this;
    }

    /**
     * Remove siteLog
     *
     * @param \A\SHB\Entity\SiteLog $siteLog
     */
    public function removeSiteLog(\A\SHB\Entity\SiteLog $siteLog)
    {
        $this->siteLog->removeElement($siteLog);
    }

    /**
     * Get siteLog
     *
     * @return \Doctrine\Common\Collections\Collection 
     */
    public function getSiteLog()
    {
        return $this->siteLog;
    }
}

记录实体:

<?php

namespace A\SHB\Entity;

use Doctrine\ORM\Mapping as ORM;

/**
 * Logs
 *
 * @ORM\Table()
 * @ORM\Entity(repositoryClass="A\SHB\Entity\LogsRepository")
 */
class Logs
{
    /**
     * @var integer
     *
     * @ORM\Column(name="id", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $id;

    /**
     * @var integer
     *
     * @ORM\Column(name="siteid", type="integer")
     */
    private $siteid;

    /**
     * @var integer
     *
     * @ORM\Column(name="dateline", type="integer")
     */
    private $dateline;

    /**
     * @var Log
     *
     * @ORM\ManyToOne(targetEntity="Sites")
     * @ORM\JoinColumns({
     *   @ORM\JoinColumn(name="site_id", referencedColumnName="id")
     * })
     */
    private $log;

    /**
     * Get id
     *
     * @return integer 
     */
    public function getId()
    {
        return $this->id;
    }

    /**
     * Set siteid
     *
     * @param integer $siteid
     * @return Logs
     */
    public function setSiteid($siteid)
    {
        $this->siteid = $siteid;

        return $this;
    }

    /**
     * Get siteid
     *
     * @return integer 
     */
    public function getSiteid()
    {
        return $this->siteid;
    }

    /**
     * Set dateline
     *
     * @param integer $dateline
     * @return Logs
     */
    public function setDateline($dateline)
    {
        $this->dateline = $dateline;

        return $this;
    }

    /**
     * Get dateline
     *
     * @return integer 
     */
    public function getDateline()
    {
        return $this->dateline;
    }

    /**
     * Set log
     *
     * @param \A\SHB\Entity\Log $log
     * @return Logs
     */
    public function setLog(\A\SHB\Entity\Log $log = null)
    {
        $this->log = $log;

        return $this;
    }

    /**
     * Get log
     *
     * @return \A\SHB\Entity\Log 
     */
    public function getLog()
    {
        return $this->log;
    }
}

控制器:

public function indexAction()
{
    $sites = $this->getDoctrine()->getRepository('ASHB:Sites')->findAll();

    foreach ($sites as $site)
    {
        $host = $site->getForum();
        // Do something ....

        $log = new Logs();
        $log->setSiteid($site->getId());
        $log->setDateline($temp['dateline']);

        $em = $this->getDoctrine()->getManager();
        $em->persist($log);
        $em->flush();
    }
    return $this->render('ASHB:Default:index.html.twig', array('sites' => $output, 'counters' => $counters));
}

现在,当我运行此代码时,出现以下错误:

SQLSTATE[23000]: Integrity constraint violation: 1048 Column 'siteid' cannot be null"

如果我在$log之前使用var_dump $em->persist($log);,那么siteid就在那里。我不确定是什么问题以及为什么将siteid设置为null。

更新1: 我尝试进行以下更改,但仍然遇到同样的错误:

/**
 * @var Log
 *
 * @ORM\ManyToOne(targetEntity="Sites", inversedBy="siteLog")
 */
private $log;

2 个答案:

答案 0 :(得分:0)

OneToMany不需要JoinColumn。所以看起来应该是documentation

class Sites
{
    /**
     * @ORM\OneToMany(targetEntity="Logs", mappedBy="log")
     */
    private $site_log;
}

class Logs
{
    /**
     * @ORM\ManyToOne(targetEntity="Sites", inversedBy="site_log")
     * @ORM\JoinColumn(name="site_id", referencedColumnName="id")
     */
    private $log;
}

为简单起见,忽略了orderBy和cascade。

答案 1 :(得分:0)

你的结构有问题,

从Logs Entity

中删除它
 /**
 * @var integer
 *
 * @ORM\Column(name="siteid", type="integer")
 */
private $siteid;

然后替换这部分

  /**
 * @var Log
 *
 * @ORM\ManyToOne(targetEntity="Sites")
 * @ORM\JoinColumns({
 *   @ORM\JoinColumn(name="site_id", referencedColumnName="id")
 * })
 */
private $log;

  /**
 * @var Log
 *
 * @ORM\ManyToOne(targetEntity="Sites" inversedBy="logs")
 */
private $site;

在您的网站中,实体将其替换为

 /**
 * @var ArrayCollection $siteLog
 *
 * @ORM\OneToMany(targetEntity="Logs", mappedBy="logs", cascade={"persist"})
 * @ORM\OrderBy({"siteid" = "ASC"})
 * @ORM\JoinColumns({
 *   @ORM\JoinColumn(name="log_id", referencedColumnName="siteid")
 * })
 */
private $logs;

 /**
 * @var ArrayCollection $siteLog
 *
 * @ORM\OneToMany(targetEntity="Logs", mappedBy="site", cascade={"persist"})
 * @ORM\OrderBy({"siteid" = "ASC"})
 * @ORM\JoinColumns({
 *   @ORM\JoinColumn(name="log_id", referencedColumnName="id")
 * })
 */
private $logs;

然后使用适当的setter和getter来获取这些新的feilds意味着将对象传递给setter函数,对于它们被映射的类(如果你不知道这部分写在注释中我也会这样做)