Doctrine custom entity repository (QueryBuilder) - sql

Howe create custom repository QueryBuilder for Room entity, witch will return all available rooms between two dates. I have two Entities Room.php and Reservation.php In RoomRepository.php i create function findAvailableRooms($from, $to) Hove i create query builder who return all rooms who do not have a reservation in the selected period? Tnx Room.php
<?php
namespace App\Entity;
use ApiPlatform\Core\Annotation\ApiResource;
use App\Controller\AvailableRoom;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Gedmo\Mapping\Annotation as Gedmo;
use Symfony\Bridge\Doctrine\IdGenerator\UuidV4Generator;
use Symfony\Component\Serializer\Annotation\Groups;
use Symfony\Component\Uid\Uuid;
use App\Repository\RoomRepository;
use Doctrine\ORM\Mapping as ORM;
use App\Controller\AvailableRoomController;
/**
* #ApiResource(
* normalizationContext={"groups"={"room:read"}},
* denormalizationContext={"groups"={"room:write"}},
* attributes={
* "pagination_client_items_per_page"=true
* },
* collectionOperations={
* "get",
* "post",
* "get_available"={
* "method"="GET",
* "path"="/rooms/available/{from}/{to}",
* "controller"=AvailableRoomController::class
* }
* }
* )
* #ORM\Entity(repositoryClass=RoomRepository::class)
*/
class Room
{
/**
* #ORM\Id
* #ORM\Column(type="uuid", unique=true)
* #ORM\GeneratedValue(strategy="CUSTOM")
* #ORM\CustomIdGenerator(class=UuidV4Generator::class)
* #Groups({"room:read"})
*/
private $id;
/**
* #ORM\Column(type="string", length=255)
* #Groups({"room:read", "room:write", "reservation:read"})
*/
private $name;
/**
* #ORM\Column(type="string", length=255)
* #Gedmo\Slug(fields={"name"})
* #Groups({"room:read", "room:write"})
*/
private $slug;
/**
* #ORM\Column(type="text", nullable=true)
* #Groups({"room:read", "room:write"})
*/
private $description;
/**
* #ORM\Column(type="datetime")
* #Gedmo\Timestampable(on="create")
* #Groups({"room:read", "room:write"})
*/
private $createdAt;
/**
* #ORM\Column(type="datetime")
* #Gedmo\Timestampable(on="update")
* #Groups({"room:read", "room:write"})
*/
private $updatedAt;
/**
* #ORM\OneToMany(targetEntity=Reservation::class, mappedBy="room")
* #Groups({"room:read", "room:write"})
*/
private $reservations;
public function __construct()
{
$this->reservations = new ArrayCollection();
}
public function getId(): ?Uuid
{
return $this->id;
}
public function getName(): ?string
{
return $this->name;
}
public function setName(string $name): self
{
$this->name = $name;
return $this;
}
public function getSlug(): ?string
{
return $this->slug;
}
public function setSlug(string $slug): self
{
$this->slug = $slug;
return $this;
}
public function getDescription(): ?string
{
return $this->description;
}
public function setDescription(?string $description): self
{
$this->description = $description;
return $this;
}
public function getCreatedAt(): ?\DateTimeInterface
{
return $this->createdAt;
}
public function setCreatedAt(?\DateTimeInterface $createdAt): self
{
$this->createdAt = $createdAt;
return $this;
}
public function getUpdatedAt(): ?\DateTimeInterface
{
return $this->updatedAt;
}
public function setUpdatedAt(?\DateTimeInterface $updatedAt): self
{
$this->updatedAt = $updatedAt;
return $this;
}
/**
* #return Collection|Reservation[]
*/
public function getReservations(): Collection
{
return $this->reservations;
}
public function addReservation(Reservation $reservation): self
{
if (!$this->reservations->contains($reservation)) {
$this->reservations[] = $reservation;
$reservation->setRoom($this);
}
return $this;
}
public function removeReservation(Reservation $reservation): self
{
if ($this->reservations->removeElement($reservation)) {
// set the owning side to null (unless already changed)
if ($reservation->getRoom() === $this) {
$reservation->setRoom(null);
}
}
return $this;
}
}
Reservation.php
<?php
namespace App\Entity;
use ApiPlatform\Core\Annotation\ApiFilter;
use ApiPlatform\Core\Annotation\ApiResource;
use ApiPlatform\Core\Bridge\Doctrine\Orm\Filter\DateFilter;
use App\Repository\ReservationRepository;
use Doctrine\ORM\Mapping as ORM;
use Gedmo\Mapping\Annotation as Gedmo;
use Symfony\Bridge\Doctrine\IdGenerator\UuidV4Generator;
use Symfony\Component\Serializer\Annotation\Groups;
use Symfony\Component\Uid\Uuid;
/**
* #ApiResource(
* normalizationContext={"groups"={"reservation:read"}},
* denormalizationContext={"groups"={"reservation:write"}},
* attributes={
* "pagination_client_items_per_page"=true
* }
* )
* #ApiFilter(DateFilter::class, properties={"dateFrom"})
* #ORM\Entity(repositoryClass=ReservationRepository::class)
*/
class Reservation
{
/**
* #ORM\Id
* #ORM\Column(type="uuid", unique=true)
* #ORM\GeneratedValue(strategy="CUSTOM")
* #ORM\CustomIdGenerator(class=UuidV4Generator::class)
* #Groups({"reservation:read"})
*/
private $id;
/**
* #ORM\Column(type="date")
* #Groups({"reservation:read", "reservation:write", "room:read"})
*/
private $dateFrom;
/**
* #ORM\Column(type="date")
* #Groups({"reservation:read", "reservation:write", "room:read"})
*/
private $dateTo;
/**
* #ORM\Column(type="json", nullable=true)
* #Groups({"reservation:read", "reservation:write", "room:read"})
*/
private $meta = [];
/**
* #ORM\ManyToOne(targetEntity=Room::class, inversedBy="reservations")
* #Groups({"reservation:read", "reservation:write"})
*/
private $room;
/**
* #ORM\Column(type="datetime")
* #Gedmo\Timestampable(on="create")
* #Groups({"reservation:read", "reservation:write", "room:read"})
*/
private $createdAt;
/**
* #ORM\Column(type="datetime")
* #Gedmo\Timestampable(on="update")
* #Groups({"reservation:read", "reservation:write", "room:read"})
*/
private $updatedAt;
public function getId(): ?Uuid
{
return $this->id;
}
public function getDateFrom(): ?\DateTimeInterface
{
return $this->dateFrom;
}
public function setDateFrom(\DateTimeInterface $dateFrom): self
{
$this->dateFrom = $dateFrom;
return $this;
}
public function getDateTo(): ?\DateTimeInterface
{
return $this->dateTo;
}
public function setDateTo(\DateTimeInterface $dateTo): self
{
$this->dateTo = $dateTo;
return $this;
}
public function getMeta(): ?array
{
return $this->meta;
}
public function setMeta(?array $meta): self
{
$this->meta = $meta;
return $this;
}
public function getRoom(): ?Room
{
return $this->room;
}
public function setRoom(?Room $room): self
{
$this->room = $room;
return $this;
}
public function getCreatedAt(): ?\DateTimeInterface
{
return $this->createdAt;
}
public function setCreatedAt(?\DateTimeInterface $createdAt): self
{
$this->createdAt = $createdAt;
return $this;
}
public function getUpdatedAt(): ?\DateTimeInterface
{
return $this->updatedAt;
}
public function setUpdatedAt(?\DateTimeInterface $updatedAt): self
{
$this->updatedAt = $updatedAt;
return $this;
}
}

Something like the following method placed in your ReservationRepository will fetch the ids of Rooms having a Reservation overlapping a specified date range:
/**
* #param \DateTimeInterface $start
* #param \DateTimeInterface $end
*
* #return array
*/
public function findRoomIdsReservedInDateRange(\DateTimeInterface $start, \DateTimeInterface $end)
{
$result = $this
->createQueryBuilder('r')
->select('r.room.id')
->andWhere('r.dateFrom < :end')
->andWhere('r.dateTo > :start')
->setParameter('start', $start)
->setParameter('end', $end)
->orderBy('r.room.id', 'ASC')
->getQuery()
->getScalarResult()
; // [['id' => 1], ['id' => 2], ['id' => 2], ['id' => 5]]
return array_unique(array_column($result, 'id')); // [1, 2, 5]
}
Then you could call that method from your RoomRepository
$exclude = $reservationRepository->findRoomIdsReservedInDateRange($start, $end);
return $this
->createQueryBuilder('room')
->andWhere('room.id not in :array')
->setParameter('array', $exclude)
->getQuery()
->getResult()
;

Related

Syntax Error - line 0, col 122: Error: Expected end of string, got 'ON'

I'm trying to use ON in my Query Builder but it returns [Syntax Error] line 0, col 122: Error: Expected end of string, got 'ON'.
Code:
public function filterChamados(Request $request)
{
$em = $this->getDoctrine()->getManager()->getRepository(Chamados::class)
->createQueryBuilder('c')->select('c.id, d.name_fantasy, c.status, c.titulo, c.description')
->join(Clients::class, 'd',Join::ON,'c.id_client = d.id');
if ($request->request->get('status')) {
$em->where('c.status = :status')
->setParameter('status', $request->request->get('status'));
};
if (strtoupper(trim($request->get('client')))) {
$em->andWhere('(d.name_fantasy=:client OR d.razao_social=:client)')
->setParameter('client', strtoupper(trim($request->get('client'))));
};
if ($request->get('open_date')) {
$em->andWhere('c.open_date >=:open_date')
->setParameter('open_date', $request->get('open_date'));
}
if ($request->get('close_date')) {
$em->andWhere('c.close_date <=:close_date')
->setParameter('close_date', $request->get('close_date'));
}
$em->getQuery()->getArrayResult();
return new JsonResponse($em);
}
If I return its DQL, I get:
SELECT c.id, d.name_fantasy, c.status, c.titulo, c.description FROM App\Entity\Chamados c INNER JOIN App\Entity\Clients d ON c.id_client = d.id WHERE (d.name_fantasy=:client OR d.razao_social=:client)
If I run the SQL directly into PGAdmin, it works.
If I change ON to WITH, it does not return errors, but the result comes empty. Plus, I can't run its SQL directly into PGAdmin.
What am I doing wrong?
EDIT:
This is my raw SQL (considering I'm using all fields):
SELECT
c.id, d.name_fantasy, c. status, c.titulo, c.description
FROM
chamados c
JOIN
clients d
ON
c.id_client_id = d.id
WHERE
c.status = 2 --:status
AND
(d.name_fantasy = 'FARMÁCIA ALGUMA COISA' OR d.razao_social = 'FARMÁCIA ALGUMA COISA') -- :client
AND
c.open_date >= '2019-03-03 10:00' --:open_date
AND
c.close_date <= '2019-09-03 18:00' --:close_date
Entity Chamados:
/**
* #ORM\Entity(repositoryClass="App\Repository\ChamadosRepository")
*/
class Chamados
{
/**
* #ORM\Id()
* #ORM\GeneratedValue()
* #ORM\Column(type="integer")
*/
private $id;
/**
* #ORM\Column(type="string")
*/
private $titulo;
/**
* #ORM\ManyToOne(targetEntity="App\Entity\Clients", inversedBy="chamados")
* #ORM\JoinColumn(nullable=false)
*/
private $id_client;
/**
* #ORM\Column(type="integer", options={"default" = 0})
*/
private $status;
/**
* #ORM\Column(type="text", nullable=true)
*/
private $description;
/**
* #ORM\ManyToMany(targetEntity="App\Entity\User", inversedBy="chamados")
*/
private $user;
/**
* #ORM\Column(type="datetime")
*/
private $open_date;
/**
* #ORM\Column(type="datetime", nullable=true)
*/
private $update_date;
/**
* #ORM\Column(type="datetime", nullable=true)
*/
private $close_date;
/**
* #ORM\OneToMany(targetEntity="App\Entity\Tramite", mappedBy="chamado")
*/
private $tramites;
public function __construct()
{
$this->user = new ArrayCollection();
$this->tramites = new ArrayCollection();
}
public function getId(): ?int
{
return $this->id;
}
public function getIdClient(): ?Clients
{
return $this->id_client;
}
public function setIdClient(?Clients $id_client): self
{
$this->id_client = $id_client;
return $this;
}
public function getStatus(): ?int
{
return $this->status;
}
public function setStatus(int $status): self
{
$this->status = $status;
return $this;
}
public function getDescription(): ?string
{
return $this->description;
}
public function setDescription(?string $description): self
{
$this->description = $description;
return $this;
}
/**
* #return Collection|User[]
*/
public function getUser(): Collection
{
return $this->user;
}
public function addUser(User $user): self
{
if (!$this->user->contains($user)) {
$this->user[] = $user;
}
return $this;
}
public function removeUser(User $user): self
{
if ($this->user->contains($user)) {
$this->user->removeElement($user);
}
return $this;
}
public function getOpenDate(): ?DateTimeInterface
{
return $this->open_date;
}
public function setOpenDate(DateTimeInterface $open_date): self
{
$this->open_date = $open_date;
return $this;
}
public function getUpdateDate(): ?DateTimeInterface
{
return $this->update_date;
}
public function setUpdateDate(?DateTimeInterface $update_date): self
{
$this->update_date = $update_date;
return $this;
}
public function getCloseDate(): ?DateTimeInterface
{
return $this->close_date;
}
public function setCloseDate(?DateTimeInterface $close_date): self
{
$this->close_date = $close_date;
return $this;
}
/**
* #return mixed
*/
public function getTitulo()
{
return $this->titulo;
}
/**
* #param mixed $titulo
* #return Chamados
*/
public function setTitulo($titulo)
{
$this->titulo = $titulo;
return $this;
}
/**
* #return Collection|Tramite[]
*/
public function getTramites(): Collection
{
return $this->tramites;
}
public function addTramite(Tramite $tramite): self
{
if (!$this->tramites->contains($tramite)) {
$this->tramites[] = $tramite;
$tramite->setChamado($this);
}
return $this;
}
public function removeTramite(Tramite $tramite): self
{
if ($this->tramites->contains($tramite)) {
$this->tramites->removeElement($tramite);
// set the owning side to null (unless already changed)
if ($tramite->getChamado() === $this) {
$tramite->setChamado(null);
}
}
return $this;
}
}
Entity Clients:
/**
* #ORM\Entity(repositoryClass="App\Repository\ClientsRepository")
*/
class Clients
{
/**
* #ORM\Id()
* #ORM\GeneratedValue()
* #ORM\Column(type="integer")
*/
private $id;
/**
* #ORM\Column(type="string", length=255)
*/
private $name_fantasy;
/**
* #ORM\Column(type="string", length=255)
*/
private $razao_social;
/**
* #ORM\Column(type="string", length=128, nullable=true)
*/
private $contact_email;
/**
* #ORM\Column(type="string", length=16, nullable=true)
*/
private $contact_telephone;
/**
* #ORM\OneToMany(targetEntity="App\Entity\Chamados", mappedBy="id_client")
*/
private $chamados;
/**
* #ORM\Column(type="boolean", options={"default"="true"})
*/
private $active;
public function __construct()
{
$this->chamados = new ArrayCollection();
}
public function getId(): ?int
{
return $this->id;
}
public function getNameFantasy(): ?string
{
return $this->name_fantasy;
}
public function setNameFantasy(string $name_fantasy): self
{
$this->name_fantasy = mb_convert_case($name_fantasy, MB_CASE_UPPER, 'UTF-8');
return $this;
}
public function getRazaoSocial(): ?string
{
return $this->razao_social;
}
public function setRazaoSocial(string $razao_social): self
{
$this->razao_social = mb_convert_case($razao_social, MB_CASE_UPPER, 'UTF-8');
return $this;
}
public function getContactEmail(): ?string
{
return $this->contact_email;
}
public function setContactEmail(?string $contact_email): self
{
$this->contact_email = $contact_email;
return $this;
}
public function getContactTelephone(): ?string
{
return $this->contact_telephone;
}
public function setContactTelephone(?string $contact_telephone): self
{
$this->contact_telephone = $contact_telephone;
return $this;
}
/**
* #return Collection|Chamados[]
*/
public function getChamados(): Collection
{
return $this->chamados;
}
public function addChamado(Chamados $chamado): self
{
if (!$this->chamados->contains($chamado)) {
$this->chamados[] = $chamado;
$chamado->setIdClient($this);
}
return $this;
}
public function removeChamado(Chamados $chamado): self
{
if ($this->chamados->contains($chamado)) {
$this->chamados->removeElement($chamado);
// set the owning side to null (unless already changed)
if ($chamado->getIdClient() === $this) {
$chamado->setIdClient(null);
}
}
return $this;
}
/**
* #return mixed
*/
public function getActive()
{
return $this->active;
}
/**
* #param mixed $active
* #return Clients
*/
public function setActive($active)
{
$this->active = $active;
return $this;
}
}
Edit 2:
The error is gone and the query is being built properly, but the result is empty.
Controller:
public function filterChamados(Request $request)
{
$em = $this->getDoctrine()->getManager()->getRepository(Chamados::class)
->createQueryBuilder('c')->select('c.id, d.name_fantasy, c.status, c.titulo, c.description')
->join('c.id_client', 'd');
if ($request->request->get('status')) {
$em->where('c.status = :status')
->setParameter('status', $request->request->get('status'));
}
if (strtoupper(trim($request->get('client')))) {
$em->andWhere('(d.name_fantasy=:client OR d.razao_social=:client)')
->setParameter('client', strtoupper(trim($request->get('client'))));
}
if ($request->get('open_date')) {
$em->andWhere('c.open_date >=:open_date')
->setParameter('open_date', $request->get('open_date'));
}
if ($request->get('close_date')) {
$em->andWhere('c.close_date <=:close_date')
->setParameter('close_date', $request->get('close_date'));
}
$em->getQuery()->getArrayResult();
return new JsonResponse($em);
}
Generated query:
[2019-08-21 17:22:31] doctrine.DEBUG: SELECT c0_.id AS id_0, c1_.name_fantasy AS name_fantasy_1, c0_.status AS status_2, c0_.titulo AS titulo_3, c0_.description AS description_4 FROM chamados c0_ INNER JOIN clients c1_ ON c0_.id_client_id = c1_.id WHERE (c1_.name_fantasy = ? OR c1_.razao_social = ?) ["PADARIA","PADARIA"] []
PgAdmin3: If I put both values inside the query and replace " by ', it works, otherwise it returns column "PADARIA" does not exist.
Inside AJAX request: it returns an empty JSON.
For some reason you have a semicolon where it should not be, try the following function, not saying it will work though:
function filterChamados(Request $request)
{
$em = $this->getDoctrine()->getManager()->getRepository(Chamados::class)
->createQueryBuilder('c')->select('c.id, d.name_fantasy, c.status, c.titulo, c.description')
->join('c.Clients', 'd', Join::ON, 'c.id_client = d.id');
if ($request->request->get('status')) {
$em->where('c.status = :status')
->setParameter('status', $request->request->get('status'));
}
if (strtoupper(trim($request->get('client')))) {
$em->andWhere('(d.name_fantasy=:client OR d.razao_social=:client)')
->setParameter('client', strtoupper(trim($request->get('client'))));
}
if ($request->get('open_date')) {
$em->andWhere('c.open_date >=:open_date')
->setParameter('open_date', $request->get('open_date'));
}
if ($request->get('close_date')) {
$em->andWhere('c.close_date <=:close_date')
->setParameter('close_date', $request->get('close_date'));
}
$em->getQuery()->getArrayResult();
return new JsonResponse($em);
}
Notice how I have removed the semicolon from the following pieces of code:
if ($request->request->get('status')) {
$em->where('c.status = :status')
->setParameter('status', $request->request->get('status'));
};
if (strtoupper(trim($request->get('client')))) {
$em->andWhere('(d.name_fantasy=:client OR d.razao_social=:client)')
->setParameter('client', strtoupper(trim($request->get('client'))));
};
Also notice how I have change the JOIN:
->join('c.Clients', 'd', Join::ON, 'c.id_client = d.id');
UPDATE:
Change this:
if(strtoupper(trim($request->get('client')))) {
$client = strtoupper(trim($request->get('client')));
$em->andWhere('d.name_fantasy=:client')
->orWhere('d.razao_social=:client')
->setParameter('client', $client);
}
Or:
if (strtoupper(trim($request->get('client')))) {
$em->andWhere('d.name_fantasy=:client OR d.razao_social=:client')
->setParameter('client', strtoupper(trim($request->get('client'))));
};
More info here.

ORM ManyToOne Unidirectional fetchAll Object array does not render in phtml Zend Framework 3

The application has built in ZF3. I have to entity with ManyToOne relationship using ORM. The issue is when i render through controller and and if fetch data via index it gives okay result but when i assign that to view and trying to render at phtml it throws an error/
/**
* Subscriptions
*
* #ORM\Table(name="subscriptions", indexes={#ORM\Index(name="CUST_ID", columns={"customer_id"}),#ORM\Index(name="SUB_TYPE_ID", columns={"subscription_type_id"})})
* #ORM\Entity
*/
class Subscriptions
{
/**
* #var integer
*
* #ORM\Column(name="id", type="integer", nullable=false)
* #ORM\Id
* #ORM\GeneratedValue(strategy="IDENTITY")
*/
private $id;
/**
* #var \Application\Entity\SubscriptionType
*
* #ORM\ManyToOne(targetEntity="Application\Entity\SubscriptionType")
* #ORM\JoinColumns({
* #ORM\JoinColumn(name="subscription_type_id", referencedColumnName="id")
* })
*/
protected $subscriptionType;
//set
public function setSubscriptionType(\Application\Entity\SubscriptionType $subscriptionType = null)
{
$this->subscriptionType = $subscriptionType;
return $this;
}
//get
public function getSubscriptionType(){
return $this->subscriptionType;
}
//other setter and getter....
}
Another Class
/**
* SubscriptionType
*
* #ORM\Table(name="subscription_type")
* #ORM\Entity
*/
class SubscriptionType
{
/**
* #var integer
*
* #ORM\Column(name="id", type="integer", nullable=false)
* #ORM\Id
* #ORM\GeneratedValue(strategy="IDENTITY")
*/
private $id;
/**
* #var string
*
* #ORM\Column(name="description", type="text", length=65535, nullable=true)
*/
private $description;
/**
* Get id
*enter code here
* #return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set description
*
* #param string $description
*
* #return SubscriptionType
*/
public function setDescription($description)
{
$this->description = $description;
return $this;
}
}
Now at controller i have wrote...
//some initiations
class AdminController extends AbstractActionController
{
//other initiations including __construct....
public function usersubscriptionsAction(){
$this->subscriptions = $this->entityManager->getRepository(Subscriptions::class)->findAll();
/*
foreach($this->subscriptions as $subscription){
//if i am checking with this it gives proper output
echo $subscription->getSubscriptionType()->getDescription();
die();
}
*/
return new ViewModel(
array(
"subscriptions" => $this->subscriptions
)
);
}
}
///i have phtml file
<?php foreach ($subscriptions as $subscription): ?>
//below line throwing an error
<?php echo $subscription->getSubscriptionType()->getDescription(); ?>
<?php endforeach; ?>
when i run it throw an erro message
Call to a member function getDescription() on null
You've got the relation mapping incorrect. Corrected the property annotation below:
/**
* #var \Application\Entity\SubscriptionType
*
* #ORM\ManyToOne(targetEntity="Application\Entity\SubscriptionType")
* #ORM\JoinColumn(name="subscription_type_id", referencedColumnName="id")
*/
protected $subscriptionType;
You had
/**
* #var \Application\Entity\SubscriptionType
*
* #ORM\ManyToOne(targetEntity="Application\Entity\SubscriptionType")
* #ORM\JoinColumns({
* #ORM\JoinColumn(name="subscription_type_id", referencedColumnName="id")
* })
*/
protected $subscriptionType;
The #ORM\JoinColumns is used for when you have a join with multiple columns, please see the docs. Though, the most common usage of JoinColumns is for a JoinTable.

Type conversion error from LifecycleEventArgs

I have no idea for this. I'm a beginner of symfony3.
code
/**
* Set createdAt
* #ORM\PrePersist()
* #param \DateTime $createdAt
*
* #return Book
*/
public function setCreatedAt($createdAt)
{
$this->createdAt = $createdAt;
return $this;
}
/**
* Get createdAt
*
* #return \DateTime
*/
public function getCreatedAt()
{
return $this->createdAt;
}
/**
* Set updateAt
*
* #param \DateTime $updateAt
*
* #return Book
*/
public function setUpdateAt($updateAt)
{
$this->updateAt = $updateAt;
return $this;
}
/**
* Get updateAt
*
* #return \DateTime
*/
public function getUpdateAt()
{
return $this->updateAt;
}
/**
* #ORM\PrePersist()
*/
public function PrePersist() {
if ($this->getCreatedAt() == null) {
$this->setCreatedAt(new \DateTime('now'));
}
$this->setUpdateAt(new \DateTime('now'));
}
/**
* #ORM\PreUpdate()
*/
public function PreUpdate() {
$this->setUpdateAt(new \DateTime('now'));
}
it gives an error report as below :
Error
Could not convert PHP value of type 'Doctrine\ORM\Event\LifecycleEventArgs' to type 'datetime'. Expected one of the following types: null, DateTime
Help me to figure it out.

Problems with Doctrine mapping in Symfony

I have been programming a project in the Symfony 3 using the Doctrine ORM. I have main entity called 'Race', which contains some fields and relations to another entities like 'RaceRelationToType', 'RaceRelationToOrganizer' and so on - you can see it in the picture of the database schema bellow. (Only for information, 'RaceRelationTo*' entities are entities which prevents change of original data.)
The problem: The problem becames when I fetch data from database using $this->em->getRepository('AppBundle:Race')->findAll();. Data in database are stored correctly, but If I fetch them, they have wrong data type. raceRelationToOrganizer variable should be of data type RaceRelationToOrganizer, not RaceRelationToSeason and so on.
Everything had worked right until I reset a database. When I insert new race to cleared database, id of raceRelationToSeason is 1, raceRelationToType is 1, raceRelationToOrganizer is 1 ans so on. Problems occured after reset of database (and reset of auto increment).
If ids of all relations are different, than it works OK. Magic? Error? Does anybody know what to do with it? Can you find some problem in files bellow? I have been trying to solve it for hours. Contents of important files are bellow.
I use yaml configuration files for ORM mapping. Race.orm.yml contains:
AppBundle\Entity\Race:
type: entity
table: race
id:
id:
type: integer
generator:
strategy: AUTO
fields:
registrationNumberOfRace:
column: registration_number_of_race
type: integer
length: 4
nullable: false
dateFrom:
column: date_from
type: date
nullable: false
dateTo:
column: date_to
type: date
nullable: false
manyToOne:
raceRelationToSeason:
targetEntity: AppBundle\Entity\RaceRelationToSeason
joinColumn:
name: race_relation_to_season
referencedColumnName: id
onDelete: RESTRICT
nullable: false
fetch: EAGER
cascade: [ persist,remove ]
raceRelationToType:
targetEntity: AppBundle\Entity\RaceRelationToType
joinColumn:
name: race_relation_to_type
referencedColumnName: id
onDelete: RESTRICT
nullable: false
fetch: EAGER
cascade: [ persist,remove ]
raceRelationToOrganizer:
targetEntity: AppBundle\Entity\RaceRelationToOrganizer
joinColumn:
name: race_relation_to_organizer
referencedColumnName: id
onDelete: RESTRICT
nullable: false
fetch: EAGER
cascade: [ persist,remove ]
raceRelationToVenue:
targetEntity: AppBundle\Entity\RaceRelationToVenue
joinColumn:
name: race_relation_to_venue
referencedColumnName: id
onDelete: RESTRICT
nullable: false
fetch: EAGER
cascade: [ persist,remove ]
Entity Race.php contains:
<?php
namespace AppBundle\Entity;
/**
* Class Race
* #package AppBundle\Entity
*/
class Race
{
/**
* #var integer Id of the race
*/
protected $id;
/**
* #var SeasonOfRace
*/
protected $seasonOfRace;
/**
* #var RaceRelationToSeason
*/
protected $raceRelationToSeason;
/**
* #var TypeOfRace
*/
protected $typeOfRace;
/**
* #var RaceRelationToType
*/
protected $raceRelationToType;
/**
* #var integer Registration number of the race which depend on the type of race
*/
protected $registrationNumberOfRace;
/**
* #var OrganizerOfRace
*/
protected $organizerOfRace;
/**
* #var RaceRelationToOrganizer
*/
protected $raceRelationToOrganizer;
/**
* #var VenueOfRace
*/
protected $venueOfRace;
/**
* #var RaceRelationToVenue
*/
protected $raceRelationToVenue;
/**
* #var \DateTime
*/
protected $dateFrom;
/**
* #var \DateTime
*/
protected $dateTo;
/**
* Race constructor.
*/
public function __construct()
{
$this->dateFrom = $this->dateTo = new \DateTime();
}
/**
* #return int
*/
public function getId()
{
return $this->id;
}
/**
* #param $id
* #return $this
*/
public function setId($id)
{
$this->id = $id;
return $this;
}
/**
* #return SeasonOfRace
*/
public function getSeasonOfRace()
{
if ($this->raceRelationToSeason) {
if ($this->raceRelationToSeason->getOriginal()) {
$this->seasonOfRace = $this->raceRelationToSeason->getOriginal();
return $this->seasonOfRace;
} else {
return $this->seasonOfRace;
}
} else {
return $this->seasonOfRace;
}
}
/**
* #param SeasonOfRace $seasonOfRace
* #return Race
*/
public function setSeasonOfRace(SeasonOfRace $seasonOfRace)
{
$this->seasonOfRace = $seasonOfRace;
if ($this->seasonOfRace) {
if ($this->raceRelationToSeason) {
$this->raceRelationToSeason->setLabel($this->seasonOfRace->getLabel());
$this->raceRelationToSeason->setShortLabel($this->seasonOfRace->getShortLabel());
$this->raceRelationToSeason->setOriginal($this->seasonOfRace);
} else {
$this->raceRelationToSeason = new RaceRelationToSeason();
$this->raceRelationToSeason->setLabel($this->seasonOfRace->getLabel());
$this->raceRelationToSeason->setShortLabel($this->seasonOfRace->getShortLabel());
$this->raceRelationToSeason->setOriginal($this->seasonOfRace);
}
}
return $this;
}
/**
* #return RaceRelationToSeason
*/
public function getRaceRelationToSeason()
{
return $this->raceRelationToSeason;
}
/**
* #param RaceRelationToSeason $raceRelationToSeason
* #return Race
*/
public function setRaceRelationToSeason(RaceRelationToSeason $raceRelationToSeason)
{
$this->raceRelationToSeason = $raceRelationToSeason;
return $this;
}
/**
* #return TypeOfRace
*/
public function getTypeOfRace()
{
if ($this->raceRelationToType) {
if ($this->raceRelationToType->getOriginal()) {
$this->typeOfRace = $this->raceRelationToType->getOriginal();
return $this->typeOfRace;
} else {
return $this->typeOfRace;
}
} else {
return $this->typeOfRace;
}
}
/**
* #param TypeOfRace $typeOfRace
* #return Race
*/
public function setTypeOfRace(TypeOfRace $typeOfRace)
{
$this->typeOfRace = $typeOfRace;
if ($this->typeOfRace) {
if ($this->raceRelationToType) {
$this->raceRelationToType->setLabel($this->typeOfRace->getLabel());
$this->raceRelationToType->setShortLabel($this->typeOfRace->getShortLabel());
$this->raceRelationToType->setOriginal($this->typeOfRace);
} else {
$this->raceRelationToType = new RaceRelationToType();
$this->raceRelationToType->setLabel($this->typeOfRace->getLabel());
$this->raceRelationToType->setShortLabel($this->typeOfRace->getShortLabel());
$this->raceRelationToType->setOriginal($this->typeOfRace);
}
}
return $this;
}
/**
* #return RaceRelationToType
*/
public function getRaceRelationToType()
{
return $this->raceRelationToType;
}
/**
* #param RaceRelationToType $raceRelationToType
* #return Race
*/
public function setRaceRelationToType(RaceRelationToType $raceRelationToType)
{
$this->raceRelationToType = $raceRelationToType;
return $this;
}
/**
* #return int
*/
public function getRegistrationNumberOfRace()
{
return $this->registrationNumberOfRace;
}
/**
* #param $registrationNumberOfRace
* #return Race
*/
public function setRegistrationNumberOfRace($registrationNumberOfRace)
{
$this->registrationNumberOfRace = $registrationNumberOfRace;
return $this;
}
/**
* #return VenueOfRace
*/
public function getVenueOfRace()
{
if ($this->raceRelationToVenue) {
if ($this->raceRelationToVenue->getOriginal()) {
$this->venueOfRace = $this->raceRelationToVenue->getOriginal();
return $this->venueOfRace;
} else {
return $this->venueOfRace;
}
} else {
return $this->venueOfRace;
}
}
/**
* #param VenueOfRace $venueOfRace
* #return Race
*/
public function setVenueOfRace(VenueOfRace $venueOfRace)
{
$this->venueOfRace = $venueOfRace;
if ($this->venueOfRace) {
if ($this->raceRelationToVenue) {
$this->raceRelationToVenue->setLabel($this->venueOfRace->getLabel());
$this->raceRelationToVenue->setShortLabel($this->venueOfRace->getShortLabel());
$this->raceRelationToVenue->setOriginal($this->venueOfRace);
} else {
$this->raceRelationToVenue = new RaceRelationToVenue();
$this->raceRelationToVenue->setLabel($this->venueOfRace->getLabel());
$this->raceRelationToVenue->setShortLabel($this->venueOfRace->getShortLabel());
$this->raceRelationToVenue->setOriginal($this->venueOfRace);
}
}
return $this;
}
/**
* #return RaceRelationToVenue
*/
public function getRaceRelationToVenue()
{
return $this->raceRelationToVenue;
}
/**
* #param RaceRelationToVenue $raceRelationToVenue
* #return Race
*/
public function setRaceRelationToVenue(RaceRelationToVenue $raceRelationToVenue)
{
$this->raceRelationToVenue = $raceRelationToVenue;
return $this;
}
/**
* #return OrganizerOfRace
*/
public function getOrganizerOfRace()
{
if ($this->raceRelationToOrganizer) {
if ($this->raceRelationToOrganizer->getOriginal()) {
$this->organizerOfRace = $this->raceRelationToOrganizer->getOriginal();
return $this->organizerOfRace;
} else {
return $this->organizerOfRace;
}
} else {
return $this->organizerOfRace;
}
}
/**
* #param OrganizerOfRace $organizerOfRace
* #return Race
*/
public function setOrganizerOfRace(OrganizerOfRace $organizerOfRace)
{
$this->organizerOfRace = $organizerOfRace;
if ($this->organizerOfRace) {
if ($this->raceRelationToOrganizer) {
$this->raceRelationToOrganizer->setLabel($this->organizerOfRace->getLabel());
$this->raceRelationToOrganizer->setShortLabel($this->organizerOfRace->getShortLabel());
$this->raceRelationToOrganizer->setOriginal($this->organizerOfRace);
} else {
$this->raceRelationToOrganizer = new RaceRelationToOrganizer();
$this->raceRelationToOrganizer->setLabel($this->organizerOfRace->getLabel());
$this->raceRelationToOrganizer->setShortLabel($this->organizerOfRace->getShortLabel());
$this->raceRelationToOrganizer->setOriginal($this->organizerOfRace);
}
}
return $this;
}
/**
* #return RaceRelationToOrganizer
*/
public function getRaceRelationToOrganizer()
{
return $this->raceRelationToOrganizer;
}
/**
* #param RaceRelationToOrganizer $raceRelationToOrganizer
* #return Race
*/
public function setRaceRelationToOrganizer(RaceRelationToOrganizer $raceRelationToOrganizer)
{
$this->raceRelationToOrganizer = $raceRelationToOrganizer;
return $this;
}
/**
* #return \DateTime
*/
public function getDateFrom()
{
return $this->dateFrom;
}
/**
* #param \DateTime $dateFrom
* #return $this
*/
public function setDateFrom(\DateTime $dateFrom)
{
$this->dateFrom = $dateFrom;
return $this;
}
/**
* #return \DateTime
*/
public function getDateTo()
{
return $this->dateTo;
}
/**
* #param \DateTime $dateTo
*/
public function setDateTo(\DateTime $dateTo)
{
$this->dateTo = $dateTo;
}
}
I solved it exactly after 23 hours, it was my fault. I want to say sorry to all who have spent their time with trying to help me.
As you can see in the database schema above, there is the table RaceRelationToType that is table between table called Race and table called TypeOfRace. This table is here because when you remove original data from TypeOfRace, data are still stored in a copy in RaceRelationToType+ - it is because of archiving data. It is same with another tables beggining with RaceRelationToXXX.
Mistake was in RaceRelationToOrganizer.php entity. I had extended RaceRelationToOrganizer entity with VenueOfRace entity instead of OrganizerOfRace entity. I don't know why, but It had worked before, but not after reset of database.
So there was no error shown, but Doctrine didn't know what to do with it (fields in all this between-tables are identical) and it mapped random data types. So that's all.
Thank you and sorry!

Use select x from y where z in symfony2 (doctrine)

So I have little problem, I don't know how I can use:
SELECT * FROM product WHERE nazwa = 'Sprite'
in Symfony. Here is my file from "Entity":
<?php
namespace My\MainBundle\Entity;
use Symfony\Component\Validator\Constraints as Assert;
use Doctrine\ORM\Mapping AS ORM;
/**
* #ORM\Entity
* #ORM\Table(name="product")
*/
class Product
{
/**
* #ORM\Column(type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* #ORM\Column(type="integer", length=10)
*/
protected $cena;
/**
* #ORM\Column(type="integer", length=10)
*/
protected $ilosc;
/**
* #ORM\Column(type="string", length=50)
*/
protected $nazwa;
public function getCena()
{
return $this->cena;
}
public function setCena($cena)
{
$this->cena = $cena;
}
public function getIlosc()
{
return $this->ilosc;
}
public function setIlosc($ilosc)
{
$this->ilosc = $ilosc;
}
public function getNazwa()
{
return $this->nazwa;
}
public function setNazwa($nazwa)
{
$this->nazwa = $nazwa;
}
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
}
I tried something like this:
$repository = $this->getDoctrine()->getRepository('MainBundle:Product');
$query = $repository->createQueryBuilder('p')->select('p')->where('p.nazwa == Sprite')->getQuery();
$test = $query->getResult();
But when I try to use it, I got an error. Somebody have idea what can be wrong?
$repository = $this->getDoctrine()->getRepository('MainBundle:Product');
$result = $repository->findByNazwa('Sprite');
or with QueryBuilder
$query = $repository->createQueryBuilder('p')->select('p')->where('p.nazwa = :nazwa')->setParameter('nazwa', 'Sprite')->getQuery();
$test = $query->getResult();
Try this:
$repository = $this->getDoctrine()->getRepository('MainBundle:Product');
$query = $repository->createQueryBuilder('p');
$query->where('p.nazwa = :brand')
->setParameter('brand', 'Sprite');
$test = $query->getQuery()->getResult();