我有两个实体:User和Event,它们处于ManyToMany关系中。 我尝试按$ user-> getEvents()的条件匹配事件,但什么也得不到。检查分析器后,我看到构建sql时标准无法正常工作,我使用了表达式lte和gte,但在sql doctrine中继续使用=。
这是我的课程 用户:
<?php
namespace App\UserBundle\Entity;
use App\CoreBundle\Entity\Event;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;
use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;
use JMS\Serializer\Annotation as JMS;
/**
* @JMS\ExclusionPolicy("all")
*
* @ORM\Entity(repositoryClass="App\UserBundle\Repository\UserRepository")
* @ORM\Table(name="users", uniqueConstraints={@ORM\UniqueConstraint(name="User",columns={"login", "email"})})
* @UniqueEntity(fields={"login","email"})
* @ORM\HasLifecycleCallbacks()
*/
class User
{
/**
* @var int
*
* @ORM\Column(name="id", type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* @ORM\Column(name="login", type="string", length=255, unique=true, nullable=false)
* @Assert\NotBlank()
*/
protected $login;
/**
* @JMS\Expose
*
* @ORM\Column(name="name", type="string", length=255, unique=true, nullable=false)
* @Assert\NotBlank()
*/
protected $name;
/**
* @JMS\Expose
*
* @ORM\Column(name="email", type="string", length=255, unique=true, nullable=false)
* @Assert\NotBlank()
*/
protected $email;
/**
* @ORM\Column(name="roles", type="array", nullable=false)
* @Assert\NotBlank()
*/
protected $roles;
/**
* @ORM\Column(name="blocked", type="boolean")
* @Assert\NotBlank()
*/
protected $blocked;
/**
* @ORM\Column(type="datetime")
*/
protected $created;
/**
* @ORM\Column(type="datetime")
*/
protected $updated;
/**
* @ORM\ManyToMany(targetEntity="App\CoreBundle\Entity\Event", inversedBy="users", cascade={"persist", "remove"})
* @ORM\JoinTable(name="users_events",
* joinColumns={@ORM\JoinColumn(name="user_id", referencedColumnName="id", onDelete="cascade")},
* inverseJoinColumns={@ORM\JoinColumn(name="event_id", referencedColumnName="id", onDelete="cascade")}
* )
*/
protected $events;
public function __construct()
{
$this->roles = array();
$this->events = new ArrayCollection();
$this->setCreated(new \DateTime());
$this->setUpdated(new \DateTime());
}
public function __toString()
{
return (string) $this->id;
}
/**
* @ORM\PreUpdate
*/
public function setUpdatedValue()
{
$this->setUpdated(new \DateTime());
}
/**
* Set created.
*
* @param \DateTime $created
*
* @return User
*/
public function setCreated($created)
{
$this->created = $created;
return $this;
}
/**
* Get created.
*
* @return \DateTime
*/
public function getCreated()
{
return $this->created;
}
/**
* Set updated.
*
* @param \DateTime $updated
*
* @return User
*/
public function setUpdated($updated)
{
$this->updated = $updated;
return $this;
}
/**
* Get updated.
*
* @return \DateTime
*/
public function getUpdated()
{
return $this->updated;
}
public function getId()
{
return $this->id;
}
/**
* Get Login.
*
* @return string
*/
public function getLogin()
{
return $this->login;
}
/**
* Set Login.
*
* @param $login
*
* @return User
*/
public function setLogin($login)
{
$this->login = $login;
return $this;
}
/**
* Get Name.
*
* @return mixed
*/
public function getName()
{
return $this->name;
}
/**
* Set Name.
*
* @param string $name
*
* @return User
*/
public function setName($name)
{
$this->name = $name;
return $this;
}
/**
* Get Email.
*
* @return mixed
*/
public function getEmail()
{
return $this->email;
}
/**
* Set Email.
*
* @param mixed $email
*
* @return User
*/
public function setEmail($email)
{
$this->email = $email;
return $this;
}
/**
* Get roles.
*
* @return mixed
*/
public function getRoles()
{
return $this->roles;
}
/**
* Set Roles.
*
* @param mixed $roles
*
* @return User
*/
public function setRoles($roles)
{
$this->roles = array();
foreach ($roles as $role) {
$this->addRole($role);
}
return $this;
}
/**
* Add role to collection.
*
* @param $role
*
* @return User
*/
public function addRole($role)
{
$role = strtoupper($role);
if (!in_array($role, $this->roles, true)) {
$this->roles[] = $role;
}
return $this;
}
/**
* Get Blocked.
*
* @return boolean
*/
public function getBlocked()
{
return $this->blocked;
}
/**
* Set Blocked.
*
* @param boolean $blocked
*
* @return User
*/
public function setBlocked($blocked)
{
$this->blocked = $blocked;
return $this;
}
/**
* Add event.
*
* @param Event $event
*
* @return User
*/
public function addEvent(Event $event)
{
if (!$this->events->contains($event)) {
$this->events[] = $event;
}
return $this;
}
/**
* Remove event.
*
* @param Event $event
*
* @return User
*/
public function removeEvent(Event $event)
{
if ($this->events->contains($event)) {
$this->events->removeElement($event);
}
return $this;
}
/**
* Get events.
*
* @return ArrayCollection
*/
public function getEvents()
{
return $this->events;
}
}
事件:
<?php
namespace App\CoreBundle\Entity;
use App\UserBundle\Entity\User;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\ORM\Mapping as ORM;
/**
* Event
*
* @ORM\Table()
* @ORM\Entity(repositoryClass="App\CoreBundle\Repository\EventRepository")
*/
class Event
{
/**
* @var integer
*
* @ORM\Column(name="id", type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* @var string
*
* @ORM\Column(name="event_name", type="string", length=50)
*/
private $eventName;
/**
* @var string
*
* @ORM\Column(name="event_description", type="string", length=160)
*/
private $eventDescription;
/**
* @var string
*
* @ORM\Column(name="event_type", type="string", length=100)
*/
private $eventType;
/**
* @var boolean
*
* @ORM\Column(name="visible", type="boolean")
*/
private $visible;
/**
* @var \DateTime
*
* @ORM\Column(name="start_date", type="datetime")
*/
private $startDate;
/**
* @var \DateTime
*
* @ORM\Column(name="end_date", type="datetime")
*/
private $endDate;
/**
* @ORM\ManyToMany(targetEntity="App\UserBundle\Entity\User", mappedBy="events")
*/
protected $users;
public function __construct()
{
$this->users = new ArrayCollection();
}
/**
* Get id
*
* @return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set eventName
*
* @param string $eventName
* @return Event
*/
public function setEventName($eventName)
{
$this->eventName = $eventName;
return $this;
}
/**
* Get eventName
*
* @return string
*/
public function getEventName()
{
return $this->eventName;
}
/**
* Set eventDescription
*
* @param string $eventDescription
* @return Event
*/
public function setEventDescription($eventDescription)
{
$this->eventDescription = $eventDescription;
return $this;
}
/**
* Get eventDescription
*
* @return string
*/
public function getEventDescription()
{
return $this->eventDescription;
}
/**
* Set eventType
*
* @param string $eventType
* @return Event
*/
public function setEventType($eventType)
{
$this->eventType = $eventType;
return $this;
}
/**
* Get eventType
*
* @return string
*/
public function getEventType()
{
return $this->eventType;
}
/**
* Set visible
*
* @param boolean $visible
* @return Event
*/
public function setVisible($visible)
{
$this->visible = $visible;
return $this;
}
/**
* Get visible
*
* @return boolean
*/
public function getVisible()
{
return $this->visible;
}
/**
* Set startDate
*
* @param \DateTime $startDate
* @return Event
*/
public function setStartDate($startDate)
{
$this->startDate = $startDate;
return $this;
}
/**
* Get startDate
*
* @return \DateTime
*/
public function getStartDate()
{
return $this->startDate;
}
/**
* Set endDate
*
* @param \DateTime $endDate
* @return Event
*/
public function setEndDate($endDate)
{
$this->endDate = $endDate;
return $this;
}
/**
* Get endData
*
* @return \DateTime
*/
public function getEndDate()
{
return $this->endDate;
}
/**
* Set users.
*
* @param ArrayCollection $users
*
* @return Event
*/
public function setUsers(ArrayCollection $users)
{
$this->users = $users;
return $this;
}
/**
* Add user.
*
* @param User $user
*
* @return Event
*/
public function addUser(User $user)
{
if (!$this->users->contains($user)) {
$this->users[] = $user;
}
return $this;
}
/**
* Get user.
*
* @return User
*/
public function getUsers()
{
return $this->users;
}
/**
* Remove user
*
* @param User $user
*/
public function removeUser(User $user)
{
$this->users->removeElement($user);
}
}
以下是我尝试查找与用户相关的事件的方法:
private function getActiveEventsCriteria($camelStyle = true, $dateAsObject = true)
{
$currentDateTime = new \DateTime();
$criteria = Criteria::create()
->where(
Criteria::expr()->andX(
Criteria::expr()->lte($camelStyle ? 'startDate' : 'start_date', $dateAsObject ? $currentDateTime : $currentDateTime->format("Y-m-d H:i:s")),
Criteria::expr()->gte($camelStyle ? 'endDate' : 'end_date', $dateAsObject ? $currentDateTime : $currentDateTime->format("Y-m-d H:i:s"))
)
)
->andWhere(Criteria::expr()->eq('visible', 1));
return $criteria;
}
public function getParticipatingEventsBy(User $user)
{
$userEvents = $user->getEvents();
if (is_null($userEvents)) return [];
return $userEvents->matching($this->getActiveEventsCriteria(false, false));
}
$this->getParticipatingEventsBy($user);
在profiler / debug中,我看到下一个sql:
SELECT
te.id AS id,
te.event_name AS event_name,
te.event_description AS event_description,
te.event_type AS event_type,
te.visible AS visible,
te.start_date AS start_date,
te.end_date AS end_date
FROM
event te
JOIN users_events t ON t.event_id = te.id
WHERE
t.user_id = ?
AND te.start_date = ?
AND te.end_date = ?
AND te.visible = ?
使用应用参数:
SELECT
te.id AS id,
te.event_name AS event_name,
te.event_description AS event_description,
te.event_type AS event_type,
te.visible AS visible,
te.start_date AS start_date,
te.end_date AS end_date
FROM
event te
JOIN users_events t ON t.event_id = te.id
WHERE
t.user_id = 14 AND
te.start_date = '2015-12-03 16:26:44' AND
te.end_date = '2015-12-03 16:26:44' AND
te.visible = 1;
我将WHERE更改为下一个:
WHERE
t.user_id = 14 AND
te.start_date <= '2015-12-03 16:26:44' AND
te.end_date >= '2015-12-03 16:26:44' AND
te.visible = 1;
使用那个sql我得到了正确的结果。
当我使用与存储库无关的相同标准时,一切正常:
public function getActiveEvents() {
return $this->matching($this->getActiveEventsCriteria());
}
public function matching(Criteria $criteria)
{
return $this->repository->matching($criteria);
}
$this->getActiveEvents();
这是格式化的sql:
SELECT
t0.id AS id_1,
t0.event_name AS event_name_2,
t0.event_description AS event_description_3,
t0.event_type AS event_type_4,
t0.visible AS visible_5,
t0.start_date AS start_date_6,
t0.end_date AS end_date_7
FROM
event t0
WHERE
(
(
t0.start_date <= ?
AND t0.end_date >= ?
)
AND t0.visible = ?
)
使用应用参数:
SELECT
t0.id AS id_1,
t0.event_name AS event_name_2,
t0.event_description AS event_description_3,
t0.event_type AS event_type_4,
t0.visible AS visible_5,
t0.start_date AS start_date_6,
t0.end_date AS end_date_7
FROM
event t0
WHERE
((t0.start_date <= '2015-12-03 17:01:47' AND t0.end_date >= '2015-12-03 17:01:47') AND
t0.visible = 1);
正如你所看到的,对于我不尝试搜索关系的情况 - 一切正常,我得到了结果。但是当我使用Criteria向用户尝试相关事件时 - 它失败并返回空结果导致错误的sql。
我使用的是php 5.6。*,symfony 2.8,doctrine 2.5.2,最新的MySQL。
任何帮助将非常感谢。 谢谢。
更新:
- 在JIRA中创建了问题:here