当使用即时加载时,onetmany关系错误


OneToMany relationship errors when using eager loading

我为用户使用FOSUserBundle,为fixture生成使用Alice,为FOSRestBundle。我有两个实体:User和Shift。一个用户可以有多个班次。下面是我的实体类,这是当我尝试以有效用户身份登录时得到的错误:

[2015-08-11 18:50:47]请求。关键:未捕获的PHP异常Symfony'Component'Debug'Exception' contextrorexception:" Notice: Undefined index: user"在/var/网址/vendor/doctrine/orm/lib/doctrine/orm/persisters/basicentitypersister.php行1758 {" Exception ":"[object] 编辑:BasicEntityPersister的第1758行正在查看mapappedby值。但我还是不知道是哪里出了问题。

编辑:还发现了这个相关的主题原则:在OneToMany Association中忽略了mapappedby的值

如果我删除fetch="EAGER"值,我可以登录,否则我得到上面的错误。我已经找了将近3个小时了,还是摸不着头脑。

My tables if it help:

CREATE TABLE `user` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `username` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
  `username_canonical` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
  `email` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
  `email_canonical` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
  `enabled` tinyint(1) NOT NULL,
  `salt` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
  `password` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
  `last_login` datetime DEFAULT NULL,
  `locked` tinyint(1) NOT NULL,
  `expired` tinyint(1) NOT NULL,
  `expires_at` datetime DEFAULT NULL,
  `confirmation_token` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
  `password_requested_at` datetime DEFAULT NULL,
  `roles` longtext COLLATE utf8_unicode_ci NOT NULL COMMENT '(DC2Type:array)',
  `credentials_expired` tinyint(1) NOT NULL,
  `credentials_expire_at` datetime DEFAULT NULL,
  `name` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
  `phone` varchar(16) COLLATE utf8_unicode_ci NOT NULL,
  `created_at` datetime NOT NULL,
  `updated_at` datetime NOT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `UNIQ_8D93D64992FC23A8` (`username_canonical`),
  UNIQUE KEY `UNIQ_8D93D649A0D96FBF` (`email_canonical`)
) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
CREATE TABLE `shift` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `user` int(11) NOT NULL,
  `break` double NOT NULL,
  `start_time` datetime NOT NULL,
  `end_time` datetime NOT NULL,
  `created_at` datetime NOT NULL,
  `updated_at` datetime NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=51 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

用户类:

<?php
namespace AppBundle'Entity;
use Doctrine'Common'Collections'ArrayCollection;
use Doctrine'ORM'Mapping as ORM;
use FOS'UserBundle'Model'User as BaseUser;
use Gedmo'Mapping'Annotation as Gedmo;
use JMS'Serializer'Annotation'ExclusionPolicy;
use JMS'Serializer'Annotation'Expose;
use Symfony'Component'Validator'Constraints as Assert;
/**
 * User
 *
 * @ORM'Table(name="user")
 * @ORM'Entity(repositoryClass="AppBundle'Data'Repository'UserRepository")
 * @ExclusionPolicy("all")
 */
class User extends BaseUser
{
    /**
     * @var integer
     *
     * @ORM'Column(name="id", type="integer")
     * @ORM'Id
     * @ORM'GeneratedValue(strategy="AUTO")
     */
    protected $id;

    /**
     * @var string
     *
     * @ORM'Column(name="name", type="string", length=255)
     * @Assert'NotBlank(message="Please enter your name.", groups={"Registration", "Profile"})
     * @Assert'Length(
     *     min=3,
     *     max=255,
     *     minMessage="The name is too short.",
     *     maxMessage="The name is too long.",
     *     groups={"Registration", "Profile"}
     * )
     * @Expose
     */
    private $name;
    /**
     * @var string
     *
     * @ORM'Column(name="phone", type="string", length=16)
     * @Expose
     */
    private $phone;
    /**
     * @var 'DateTime
     *
     * @Gedmo'Timestampable(on="create")
     * @ORM'Column(name="created_at", type="datetime")
     * @Expose
     */
    private $createdAt;
    /**
     * @var 'DateTime
     *
     * @Gedmo'Timestampable(on="update")
     * @ORM'Column(name="updated_at", type="datetime")
     * @Expose
     */
    private $updatedAt;
    /**
     * @var ArrayCollection
     * @ORM'OneToMany(targetEntity="Shift", mappedBy="user", fetch="EAGER")
     * @Expose
     */
    private $shifts;

    public function __construct()
    {
        $this->shifts = new ArrayCollection();
        parent::__construct();
    }
    /**
     * Get id
     *
     * @return integer 
     */
    public function getId()
    {
        return $this->id;
    }
    /**
     * Set name
     *
     * @param string $name
     * @return User
     */
    public function setName($name)
    {
        $this->name = $name;
        return $this;
    }
    /**
     * Get name
     *
     * @return string 
     */
    public function getName()
    {
        return $this->name;
    }
    /**
     * Set email
     *
     * @param string $email
     * @return User
     */
    public function setEmail($email)
    {
        $this->email = $email;
        return $this;
    }
    /**
     * Get email
     *
     * @return string 
     */
    public function getEmail()
    {
        return $this->email;
    }
    /**
     * Set phone
     *
     * @param string $phone
     * @return User
     */
    public function setPhone($phone)
    {
        $this->phone = $phone;
        return $this;
    }
    /**
     * Get phone
     *
     * @return string 
     */
    public function getPhone()
    {
        return $this->phone;
    }
    /**
     * Set createdAt
     *
     * @param 'DateTime $createdAt
     * @return User
     */
    public function setCreatedAt($createdAt)
    {
        $this->createdAt = $createdAt;
        return $this;
    }
    /**
     * Get createdAt
     *
     * @return 'DateTime 
     */
    public function getCreatedAt()
    {
        return $this->createdAt;
    }
    /**
     * Set updatedAt
     *
     * @param 'DateTime $updatedAt
     * @return User
     */
    public function setUpdatedAt($updatedAt)
    {
        $this->updatedAt = $updatedAt;
        return $this;
    }
    /**
     * Get updatedAt
     *
     * @return 'DateTime 
     */
    public function getUpdatedAt()
    {
        return $this->updatedAt;
    }
    /**
     * Add shifts
     *
     * @param 'AppBundle'Entity'Shift $shifts
     * @return User
     */
    public function addShift('AppBundle'Entity'Shift $shifts)
    {
        $this->shifts[] = $shifts;
        return $this;
    }
    /**
     * Remove shifts
     *
     * @param 'AppBundle'Entity'Shift $shifts
     */
    public function removeShift('AppBundle'Entity'Shift $shifts)
    {
        $this->shifts->removeElement($shifts);
    }
    /**
     * Get shifts
     *
     * @return 'Doctrine'Common'Collections'Collection 
     */
    public function getShifts()
    {
        return $this->shifts;
    }
}

转变类:

<?php
namespace AppBundle'Entity;
use Gedmo'Mapping'Annotation as Gedmo;
use Doctrine'ORM'Mapping as ORM;
use JMS'Serializer'Annotation'ExclusionPolicy;
use JMS'Serializer'Annotation'Expose;
/**
 * Shift
 *
 * @ORM'Table()
 * @ORM'Entity(repositoryClass="AppBundle'Data'Repository'ShiftRepository")
 * @ExclusionPolicy("all")
 */
class Shift
{
    /**
     * @var integer
     *
     * @ORM'Column(name="id", type="integer")
     * @ORM'Id
     * @ORM'GeneratedValue(strategy="AUTO")
     */
    private $id;
    /**
     * @var integer
     *
     * @ORM'Column(name="user", type="integer")
     * @ORM'ManyToOne(targetEntity="User", inversedBy="shifts", fetch="EAGER")
     * @Expose
     */
    private $user;
    /**
     * @var float
     *
     * @ORM'Column(name="break", type="float")
     * @Expose
     */
    private $break;
    /**
     * @var 'DateTime
     *
     * @ORM'Column(name="start_time", type="datetime")
     * @Expose
     */
    private $startTime;
    /**
     * @var 'DateTime
     *
     * @ORM'Column(name="end_time", type="datetime")
     * @Expose
     */
    private $endTime;
    /**
     * @var 'DateTime
     *
     * @Gedmo'Timestampable(on="create")
     * @ORM'Column(name="created_at", type="datetime")
     * @Expose
     */
    private $createdAt;
    /**
     * @var 'DateTime
     *
     * @Gedmo'Timestampable(on="update")
     * @ORM'Column(name="updated_at", type="datetime")
     * @Expose
     */
    private $updatedAt;

    /**
     * Get id
     *
     * @return integer 
     */
    public function getId()
    {
        return $this->id;
    }
    /**
     * Set user
     *
     * @param User $user
     * @return Shift
     */
    public function setUser($user)
    {
        $this->user = $user;
        return $this;
    }
    /**
     * Get user
     *
     * @return User
     */
    public function getUser()
    {
        return $this->user;
    }
    /**
     * Set break
     *
     * @param float $break
     * @return Shift
     */
    public function setBreak($break)
    {
        $this->break = $break;
        return $this;
    }
    /**
     * Get break
     *
     * @return float 
     */
    public function getBreak()
    {
        return $this->break;
    }
    /**
     * Set startTime
     *
     * @param 'DateTime $startTime
     * @return Shift
     */
    public function setStartTime($startTime)
    {
        $this->startTime = $startTime;
        return $this;
    }
    /**
     * Get startTime
     *
     * @return 'DateTime 
     */
    public function getStartTime()
    {
        return $this->startTime;
    }
    /**
     * Set endTime
     *
     * @param 'DateTime $endTime
     * @return Shift
     */
    public function setEndTime($endTime)
    {
        $this->endTime = $endTime;
        return $this;
    }
    /**
     * Get endTime
     *
     * @return 'DateTime 
     */
    public function getEndTime()
    {
        return $this->endTime;
    }
    /**
     * Set createdAt
     *
     * @param 'DateTime $createdAt
     * @return Shift
     */
    public function setCreatedAt($createdAt)
    {
        $this->createdAt = $createdAt;
        return $this;
    }
    /**
     * Get createdAt
     *
     * @return 'DateTime 
     */
    public function getCreatedAt()
    {
        return $this->createdAt;
    }
    /**
     * Set updatedAt
     *
     * @param 'DateTime $updatedAt
     * @return Shift
     */
    public function setUpdatedAt($updatedAt)
    {
        $this->updatedAt = $updatedAt;
        return $this;
    }
    /**
     * Get updatedAt
     *
     * @return 'DateTime 
     */
    public function getUpdatedAt()
    {
        return $this->updatedAt;
    }
}

我需要执行的连接查询不工作,并抛出以下错误:

$shiftsQuery = $this->createQueryBuilder('s1')
            ->addSelect('u')
            ->from('AppBundle:Shift', 's2')
            ->leftJoin('s1.user', 'u')
            ->where('u = :user')
            ->andWhere('s1.user = :user AND s2.user != :user')
            ->andWhere('s2.startTime BETWEEN s1.startTime AND s1.endTime OR s2.endTime BETWEEN s1.startTime AND s1.endTime')
            ->setParameter('user', $user)
            ->groupBy('s1.id')
        ;
        $result = $shiftsQuery
            ->getQuery()
            ->setFetchMode('AppBundle'Entity'User', 'shifts', 'Doctrine'ORM'Mapping'ClassMetadata::FETCH_EAGER)
            ->getResult();
错误:

Doctrine'ORM'Query'QueryException::semanticalError('line 0, col 62 near 'u, AppBundle:Shift': Error: Class AppBundle'Entity'Shift没有关联命名用户',object(QueryException)) in/var/http:///vendor/doctrine/orm/lib/doctrine/orm/Query/parser .php行483

在Shift.php实体中,$user属性没有正确的注释,尝试如下:

/**
 * @var User
 * @ORM'ManyToOne(targetEntity="User", inversedBy="shifts", fetch="EAGER")
 * @ORM'JoinColumn(name="user_id", referencedColumnName="id")
 * @Expose
 **/
private $user;
然后修改PHP的doctrine:schema:update——force或doctrine:migrations:diff,然后向上迁移。

Dan Mironis上面的注释注释是问题的一部分。另一部分,是我如何定义固定装置。在进行此更新后,我的原始帖子中的查询按预期工作。我只是在班次上随机分配一个用户id,所以我从:

更新它
AppBundle'Entity'Shift:
    shift{1..50}:
        userId: <numberBetween(1, 2)>
        break: <numberBetween(1, 8)>
        startTime: <dateTimeBetween('8AM', '12PM')>
        endTime: <dateTimeBetween($startTime, '+8 hours')>

:

AppBundle '实体'转变:转变{20}1 . .:用户:@user2打破:开始时间:endTime:

shift{21..40}:
    user: @user3
    break: <numberBetween(1, 8)>
    startTime: <dateTimeBetween('now', '+3 days')>
    endTime: <dateTimeBetween('now', '+3 days')>
shift{41..60}:
    user: @user4
    break: <numberBetween(1, 8)>
    startTime: <dateTimeBetween('now', '+3 days')>
    endTime: <dateTimeBetween('now', '+3 days')>
shift{61..80}:
    user: @user5
    break: <numberBetween(1, 8)>
    startTime: <dateTimeBetween('now', '+3 days')>
    endTime: <dateTimeBetween('now', '+3 days')>