I'm trying to do a join between 2 tables, but I get this error:
Message: SQLSTATE[42000]: Syntax error or access violation: 1064 You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '' at line 1
This is the code:
Page model
public function __construct()
{
$this->pages_meta = new \Doctrine\Common\Collections\ArrayCollection();
}
/**
* #var integer $id
* #Id #Column(type="integer")
* #GeneratedValue
*/
private $id;
/**
* #var integer $layout
* #Column(type="string")
*/
private $layout;
/**
* #var string $name
* #Column(type="string")
*/
private $name;
/**
* #var string $title
* #Column(type="string")
*/
private $title;
/**
* #var string $slug
* #Column(type="string")
*/
private $slug;
/**
* #var string $options
* #Column(type="integer")
*/
private $content_id;
/**
* #var integer $user_id
* #Column(type="integer")
*/
private $user_id;
/**
* #var string $created_at
* #Column(type="datetime")
*/
private $created_at;
/**
* #var string $language
* #Column(type="string")
*/
private $language;
/**
* #OneToMany(targetEntity="Default_Model_PageMeta", mappedBy="page_id")
* #JoinColumn(name="id", referencedColumnName="page_id")
*/
private $meta;
... (getters and setters)
PageMeta Model
/**
* #var integer $id
* #Id #Column(type="integer")
* #GeneratedValue
*/
private $id;
/**
* #var integer $page_id
* #Column(type="integer")
*/
private $page_id;
/**
* #var integer $key
* #Column(type="string")
*/
private $key;
/**
* #var integer $value
* #Column(type="string")
*/
private $value;
... (getters and setters)
The join Syntax
$doctrine = Zend_Registry::get('doctrine');
$request = Zend_Controller_Front::getInstance()->getRequest();
$qb = $doctrine->_em->createQueryBuilder()
->select('p, m')
->from('Default_Model_Page', 'p')
->join('p.meta', 'm');
$query = $qb->getQuery();
$page = $query->getResult();
Zend_Debug::dump($page); die;
Any idea what I'm doing wrong?
Thanks in advance!
It doesn't look like you have told Doctrine how to associate a Page model with a PageMeta model. I can guess that the foreign key in the table for PageMeta is page_id, but that doesn't appear anywhere in your annotations.
In the PageMeta model, try:
/**
* The page
*
* #var Default_Model_Page
* #OneToOne(targetEntity="Default_Model_Page")
* #JoinColumn(name="page_id", referencedColumnName="id")
*/
private $page;
Then in your query, you should be able to do:
$qb = $doctrine->_em->createQueryBuilder()
->select('p, m')
->from('Default_Model_PageMeta', 'm')
->join('m.page', 'p');
Not tested, but something like this should work.
Don't map the db columns you need for a relation as both #Column and #ManyToOne (or OneToOne), but always choose one. For most relations you'll want the association mappings (#ManyToOne, etc) and need to drop the #Column.
Doctrine will behave very erratic if you use both.
/**
* #Entity
*/
class Page
{
/**
* #OneToMany(targetEntity="PageMeta", mappedBy="page")
*/
private $meta;
public function __construct() {
$this->meta = new \Doctrine\Common\Collections\ArrayCollection();
}
}
/**
* #Entity
*/
class PageMeta
{
// Remove the property $page_id
/**
* #ManyToOne(targetEntity="Page", inversedBy="meta")
* #JoinColumn(name="page_id", referencedColumnName="id")
*/
private $page;
}
You can find more info on assiciations here.
Related
there is the situation :
I would like to send information to my REST API (working on Symfony), but when i tried to send this line, i got some errors that i don't understand, like : This one .
I really tried to resolve it alone, but nothing helped me on forums.
I think about an attribute than can't probably be set to editiion, or the reverse : an attribute which is not in edition and has to be.
This is what i want : be able to modify "dateCommande" (attribute for Purchase Date) , "statut" (used for see the statement of the purchase) and "idUsager" (used for put an id for a user); and finally be able to create automatically an id ("$id").
Thanks beforehand to help me ! ^^
Code of my class "Categorie.php" :
namespace App\Entity;
use Doctrine\ORM\Mapping as ORM;
use ApiPlatform\Core\Annotation\ApiResource;
use ApiPlatform\Core\Annotation\ApiFilter;
use ApiPlatform\Core\Bridge\Doctrine\Orm\Filter\SearchFilter;
use ApiPlatform\Core\Bridge\Doctrine\Orm\Filter\RangeFilter;
use Symfony\Component\Serializer\Annotation\Groups;
use Symfony\Component\Validator\Constraints\NotNull;
use Symfony\Component\Validator\Constraints\NotBlank;
/**
* Commande
*
* #ORM\Table(name="commande", indexes={#ORM\Index(name="IDX_6EEAA67DCF034CDB", columns={"id_usager_id"})})
* #ORM\Entity
* #ApiResource(normalizationContext={"groups"={"commande"},"enable_max_depth"=true},denormalizationContext={"groups"={"commandeecriture"},"enable_max_depth"=true})
*/
class Commande
{
/**
* #var int
*
* #ORM\Column(name="id", type="integer", nullable=false)
* #ORM\Id
* #ORM\GeneratedValue(strategy="IDENTITY")
* #Groups({"commande"})
* #NotNull(message="L'id ne peut être null")
*/
private $id;
/**
* #var \DateTime
*
* #ORM\Column(name="date_commande", type="date", nullable=false)
* #Groups({"commande","commandeecriture"})
* #NotBlank(message="Date non renseignée")
*/
private $dateCommande;
/**
* #var string
*
* #ORM\Column(name="statut", type="string", length=255, nullable=false)
* #Groups({"commande","commandeecriture"})
* #NotBlank(message="Statut non renseigné")
*/
private $statut;
/**
* #var User
*
* #ORM\ManyToOne(targetEntity="User")
* #ORM\JoinColumns({
* #ORM\JoinColumn(name="id_usager_id", referencedColumnName="id")
* })
* #Groups({"commande", "commandeecriture"})
* #NotNull(message="L'id ne peut être null")
*/
private $idUsager;
/**
* Constructor
*/
public function __construct()
{
$this->idArticle = new \Doctrine\Common\Collections\ArrayCollection();
}
/**
* #return int
*/
public function getId(): int
{
return $this->id;
}
/**
* #param int $id
*/
public function setId(int $id): void
{
$this->id = $id;
}
/**
* #return \DateTime
*/
public function getDateCommande(): \DateTime
{
return $this->dateCommande;
}
/**
* #param \DateTime $dateCommande
*/
public function setDateCommande(\DateTime $dateCommande): void
{
$this->dateCommande = $dateCommande;
}
/**
* #return string
*/
public function getStatut(): string
{
return $this->statut;
}
/**
* #param string $statut
*/
public function setStatut(string $statut): void
{
$this->statut = $statut;
}
/**
* #return User
*/
public function getIdUsager(): User
{
return $this->idUsager;
}
/**
* #param User $idUsager
*/
public function setIdUsager(User $idUsager): void
{
$this->idUsager = $idUsager;
}
}
api-platform uses IRI instead of entity ids, try to replace idUsager="1" by idUsager="/usager/1". I'm guessing usager is the name of the related entity but if it's not then you just need to replace the actual name in the snippet in general it must be /related-entity-name/id
I try to work Doctrine2 Mapping out but after 8 hours of problems I really need your help, please.
I have 3 PostgreSQL table, The first one is house
Column | Type | Modifiers
---------+----------------+----------------------------------------------------
id | integer | not null default nextval('house_id_seq'::regclass)
name | character(255) | not null
address | character(255) |
rooms | integer | not null
Indexes:
"house_pkey" PRIMARY KEY, btree (id)
Referenced by:
TABLE "room" CONSTRAINT "room_house_id_fkey" FOREIGN KEY (house_id) REFERENCES house(id) ON UPDATE CASCADE ON DELETE CASCADE
and the second one is
Table "public.room"
Column | Type | Modifiers
-----------+------------------------+---------------------------------------------------
id | integer | not null default nextval('room_id_seq'::regclass)
name | character varying(255) |
room_type | integer |
vacant | boolean |
house_id | integer |
Indexes:
"room_pkey" PRIMARY KEY, btree (id)
Foreign-key constraints:
"room_house_id_fkey" FOREIGN KEY (house_id) REFERENCES house(id) ON UPDATE CASCADE ON DELETE CASCADE
and the last one is
Table "public.category"
Column | Type | Modifiers
------------+----------------+-------------------------------------------------------
id | integer | not null default nextval('category_id_seq'::regclass)
name | character(255) | not null
min_person | integer | not null
max_person | integer | not null
Indexes:
"category_pkey" PRIMARY KEY, btree (id)
I insert a FK on room_house_id that references house.id on House table .
In my Zend Framework2 I have my entities declare as
namespace Structures\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* Structures\Entity\House
*
* #ORM\Table(name="house")
* #ORM\Entity(repositoryClass="Structures\Entity\Repository\HouseRepository")
*/
class House
{
/**
* #var integer $id
*
* #ORM\Column(name="id", type="integer", nullable=false)
* #ORM\Id
* #ORM\GeneratedValue(strategy="SEQUENCE")
* #ORM\SequenceGenerator(sequenceName="house_id_seq", allocationSize=1, initialValue=1)
*/
private $id;
/**
* #var string $name
*
* #ORM\Column(name="name", type="string", length=255, nullable=false)
*/
private $name;
/**
* #var string $address
*
* #ORM\Column(name="address", type="string", length=255)
*/
private $address;
/**
* #var string $rooms
*
* #ORM\Column(name="rooms", type="integer", nullable=false)
*/
private $rooms;
/**
*
* #ORM\OneToMany(targetEntity="Structures\Entity\Room", mappedBy="house", cascade={"remove", "persist"})
*/
protected $house_room;
}
/**
* Structures\Entity\Room
*
* #ORM\Table(name="room")
* #ORM\Entity(repositoryClass="Structures\Entity\Repository\RoomRepository")
*/
class Room {
/**
* #var integer $id
*
* #ORM\Column(name="id", type="integer", nullable=false)
* #ORM\GeneratedValue(strategy="AUTO")
* #ORM\Id
*/
private $id;
/**
* #var string $name
*
* #ORM\Column(name="name", type="string", length=255,nullable=false)
*/
private $name;
/**
* #var boolean $vacant
*
* #ORM\Column(name="vacant", type="boolean", nullable=false)
*/
private $vacant;
/**
* #var Structures\Entity\Category
*
* #ORM\ManyToOne(targetEntity="Structures\Entity\Category" , cascade={"persist", "remove"})
* #ORM\JoinColumns({
* #ORM\JoinColumn(name="room_type", referencedColumnName="id")
* })
*/
private $category;
/**
* #ORM\ManyToOne(targetEntity="Structures\Entity\House", inversedBy="house_room", cascade={"remove", "persist"})
*
*/
private $house;
}
/**
* Structures\Entity\Category
*
* #ORM\Table(name="category")
* #ORM\Entity(repositoryClass="Structures\Entity\Repository\CategoryRepository")
*
*/
class Category {
/**
* #var integer $id
*
*
* #ORM\Column(name="id", type="integer", nullable=false)
* #ORM\GeneratedValue(strategy="AUTO")
* #ORM\Id
*
*/
private $id;
/**
* #var string $name
*
* #ORM\Column(name="name", type="string", length=255, nullable=false)
*
*/
private $name;
/**
* #var integer $min_person
* #ORM\Column(name="min_person", type="integer" , nullable=false)
*/
private $min_person;
/**
* #var integer $max_person
* #ORM\Column(name="max_person", type="integer", nullable=false)
*/
private $max_person;
}
The relationship with Room and Category works as well.
The one concerns Room and House Table doesn't work at all. I cannot succeed in mapping the FK house_id with the id column on House table. All edit / save operation fails and the house_id is alway sets to NULL.
Please let me understand where I've made mistakes, I'm driving crazy
UPDATE :
I try to change the relationship between House and Room.
I delete the OneToMany on the House's side and change the ManyToOne in
/**
* #var Structure\Entity\Structure
*
* #ORM\ManyToOne(targetEntity="Structures\Entity\House")
* #ORM\JoinColumns({
* #ORM\JoinColumn(name="house_id", referencedColumnName="id", nullable=FALSE)
* })
*/
private $house;
When I fetch a room with
$room = $this->roomService->getRoom($id);
var_dump($room);
I have
object(Structures\Entity\Room)#383 (4)
{
["id":"Structures\Entity\Room":private]=> int(77)
["name":"Structures\Entity\Room":private]=> string(33) "my room"
["structure":"Structures\Entity\Room":private]=> object(Structures\Entity\House)#339 (4) {
["id":"Structures\Entity\House":private]=> int(3)
["name":"Structures\Entity\House":private]=> string(255) "hotel2b "
["address":"Structures\Entity\House":private]=> string(255) "hotel2b avenue"
["number_of_rooms":"Structures\Entity\House":private]=> int(20) }
["house_id":"Structures\Entity\Room":private]=> int(3)
}
If I use the OneToMany relationship var_dump($room) returns me a full page of I don't know what it means dump !
Still, when Edit a room, the column house_is is alway sets to NULL.
Still working on
UPDATE : 09 March
After a couple of hours spend reading tutorial, I write everything from start.
House Entity does not exits anymore. Structure Entity is the new one.
My problem : Use Doctrine2 to add and edit data with OneToMany and ManyToOne relationship.
My solution :
My Entities are
namespace Structures\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* Structures\Entity\Structure
*
* #ORM\Table(name="room")
* #ORM\Entity(repositoryClass="Structures\Entity\Repository\RoomRepository")
*/
class Room {
/**
* #var integer $id
*
* #ORM\Column(name="id", type="integer", nullable=false)
* #ORM\GeneratedValue(strategy="AUTO")
* #ORM\Id
*/
private $id;
/**
* #var string $name
*
* #ORM\Column(name="name", type="string", length=255,nullable=false)
*
*/
private $name;
/**
* #var integer structure_id
* #ORM\Column(name="structure_id", type="integer", nullable=false)
*/
private $structure_id;
/**
* #var Structure\Entity\Structure
*
* #ORM\ManyToOne(targetEntity="Structure", inversedBy="rooms")
* #ORM\JoinColumns({
* #ORM\JoinColumn(name="structure_id", referencedColumnName="id")
* })
*/
private $structure;
public function __construct()
{
// $this->structure = new \Doctrine\Common\Collections\ArrayCollection();
}
/**
* #param $data
*/
public function exchangeArray($data)
{
$this->fillWith($data);
}
/**
* #param $data
* #return Room
*/
public static function createFromArray($data)
{
$room = new Room();
$room->fillWith($data);
return $room;
}
public function updateFromArray($room)
{
$structure_id = $room->getStructureId();
$structure = $this->getStructure($structure_id);
$room->setStructure($structure);
return $room;
}
/**
* Sets id
* #param $i_id
*/
private function set_Id($i_id) {
$this->id = $i_id;
}
/**
* Gets id
* #return integer
*
*/
public function getId() {
return $this->id;
}
/**
* Set name
* #param string name
*
*/
public function setName($name) {
$this->name = $name;
}
/**
* Get name
* #return string
*
*/
public function getName() {
return $this->name;
}
public function getStructureId()
{
return $this->structure_id;
}
/**
*
* #return \Doctrine\Common\Collections\ArrayCollection|Structure\Entity\Structure
*/
public function getStructure() {
return $this->structure;
}
public function setStructure($structure) {
$this->structure = $structure;
}
And Structure
namespace Structures\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* Structures\Entity\Structure
*
* #ORM\Table(name="structure")
* #ORM\Entity(repositoryClass="Structures\Entity\Repository\StructureRepository")
*/
class Structure {
/**
* #var integer $id
*
* #ORM\Column(name="id", type="integer", nullable=false)
* #ORM\Id
* #ORM\GeneratedValue(strategy="SEQUENCE")
* #ORM\SequenceGenerator(sequenceName="structure_id_seq", allocationSize=1, initialValue=1)
*
*/
private $id;
/**
* #var string address
*
* #ORM\Column(name="name", type="string", length=255,nullable=false)
*/
private $name;
/**
* #var string address
*
* #ORM\Column(name="address", type="string", length=255,nullable=false)
*
*/
private $address;
/**
* #var integer $rooms
*
* #ORM\Column(name="number_of_rooms", type="integer", nullable=false)
*/
private $number_of_rooms;
/**
* #ORM\OneToMany(targetEntity="Room", mappedBy="structure")
*/
private $rooms;
public function __construct() {
$this->rooms = new \Doctrine\Common\Collections\ArrayCollection();
}
public function exchangeArray($data) {
$this->fillWith($data);
}
public static function createFromArray($data)
{
$structure = new Structure();
$structure->fillWith($data);
return $structure;
}
private function set_Id($i_id) {
$this->id = $i_id;
}
/**
* Get id
* #return integer
*
*/
public function getId() {
return $this->id;
}
/**
* Set name
* #param string name
*
*/
public function setName($name) {
$this->name = $name;
}
/**
* Get name
* #return string
*
*/
public function getName() {
return $this->name;
}
/**
* Set address
* #param string address
*
*/
public function setAddress($address) {
$this->address = $address;
}
/**
* Get address
* #return string
*
*/
public function getAddress() {
return $this->address;
}
/**
* Set rooms
* #params integer rooms
*
*/
public function setRoom($room) {
$this->rooms = $room;
}
/**
* Get rooms
* #return integer
*
*/
public function getRoom() {
return $this->rooms;
}
/**
* #param $rooms
*/
public function setNumberOfRooms($number_of_rooms) {
$this->number_of_rooms = $number_of_rooms;
}
/**
* #return int
*/
public function getNumberOfRooms() {
return $this->number_of_rooms;
}
When I create a new Room I call a function to process my Zend\Form\Form data
public function processForm() {
if ($this->request->isPost()) {
// get the post data
$post = $this->request->getPost()->toArray();
// fill form
$this->form->setData($post);
// check if form is valid
if (!$this->form->isValid()) {
//prepare view
$view = new ViewModel(array('form' => $this->form,
'title' => 'Process Form :
Some errors during rooms processing'));
$view->setTemplate('structures/rooms/create');
return $view;
}
/* here I set the structure's Id from $structure obj gets from
$this->params('id')
*/
$structure = $this->getStructureFromQuerystring();
$post['structure_id'] = $structure->getId();
/* here I call a service method to create a Room instance and fills it
with data from $this->form
*/
$return = $this->roomService->insertRoomFromArray($post);
if ($return ) {
$this->flashMessenger()->setNamespace('rooms')->addMessage
('Operation executed correctly');
return $this->redirect()->toRoute('rooms/index');
}
}
Service Method does
public function insertRoomFromArray(array $am_formData) {
/* here I get the structure with the id stores in $am_formData*/
$structure = $this->getStructure($am_formData['structure_id']);
/* here I copy the $structure obj in $am_formData array */
$am_formData['structure'] = $structure;
/* here I call the Room Entity method createFromArray to create the Room */
$I_event = Room::createFromArray($am_formData);
/* here I call the mapper method to persist data */
$this->I_mapper->saveRoom($I_event);
return $I_event;
}
Room Entity
public static function createFromArray($data)
{
/* create new Room obj */
$room = new Room();
/* fill with data */
$room->fillWith($data);
return $room;
}
public function fillWith($data) {
$this->id = (isset($data['id'])) ? $data['id'] : null;
$this->name = (isset($data['name'])) ? $data['name'] : null;
/* here I copy the structure obj for relationship */
$this->structure = (isset($data['structure'])) ? $data['structure'] : null;
}
Mapper Entity
public function saveRoom(\Structures\Entity\Room $room)
{
$this->entityManager->persist($room);
$this->entityManager->flush();
}
It works and the new room has the correct structure's id sets.
What when I have to edit a room ? My solution
From the controller
public function editAction() {
/* Gets the room obj by $this->params('id') */
$room = $this->getRoomFromQueryString();
$this->form->bind($room);
$view = $this->processEditForm($room);
if (!$view instanceof ViewModel) {
$view = new ViewModel(array('form' => $this->form,
'title' => 'Edit Room: ' . $room->getName() ,
'structure' => $room->getStructure()));
$view->setTemplate('structures/rooms/create');
}
return $view;
}
private function processEditForm(Room $room)
{
if ($this->request->isPost()) {
$post = $this->request->getPost()->toArray();
/* here I put structure_id in $post array. */
$post['structure_id'] = $room->getStructure()->getId();
/* After this , my previous room obj is update with the data come from the
From, but the $structure entity is NULL. I don't know why. I will use the id
stores in $post['structure_id'] to fetch the Structure obj*/
$this->form->setData($post);
if (!$this->form->isValid()) {
$view = new ViewModel(array('form' => $this->form,
'title' => 'Some erros during rooms processing'));
$view->setTemplate('structures/rooms/create');
return $view;
}
$return = $this->roomService->updateRoomFromArray($room);
if ($return ) {
$this->flashMessenger()->setNamespace('rooms')->addMessage('Operation executed correctly');
return $this->redirect()->toRoute('rooms/index');
}
else {
echo "Errore durante Editing della room";
}
}
}
The Service Method to update data
public function updateRoomFromArray(Room $room) {
/* I call the Room Entity method to update my room /
$I_event = Room::updateFromArray($room);
/ persist data */
$this->I_mapper->updateRoom($room);
}
public function updateFromArray($room)
{
/* here I fetch the Structure's relationship my Room obj belongs to */
$structure_id = $room->getStructureId();
$structure = $this->getStructure($structure_id);
/* here I set the link*/
$room->setStructure($structure);
return $room;
}
public function updateRoom(\Structures\Entity\Room $room)
{
$this->entityManager->merge($room);
$this->entityManager->flush();
}
I'd like to know your opinion about my code, please. Is the right way to work with Doctrine2 ? thanks in advance
The syntax of your annotation is not correct.
Your ManyToOne association must have this following simple format:
#ManyToOne(targetEntity="Structures\Entity\House", inversedBy="features")
#JoinColumn(name="house_id", referencedColumnName="id")
Take a look at the documentation for more informations:
http://doctrine-orm.readthedocs.org/en/latest/reference/association-mapping.html#one-to-many-bidirectional
Hope this helps.
I'm trying to workout a basic join in a query for MySQL-tables. After reading the documentation and some questions on Stackoverflow, I still can't get it to work ...
The error:
Message: [Semantical Error] line 0, col 74 near 'o': Error: Class Client_Model_Client has no association named Contact_Model_Contact
The code here, are my models and the query I'm working on:
Model client
<?php
/**
* #Table(name="client_clients")
* #Entity(repositoryClass="Client_Model_ClientRepository")
*/
class Client_Model_Client {
public function __construct()
{
$this->contacts = new \Doctrine\Common\Collections\ArrayCollection();
}
/**
* #var integer $id
* #Id #Column(type="integer")
* #GeneratedValue
*/
private $id;
/**
* #var string $name
* #Column(type="string")
*/
private $name;
/**
* #var string $address
* #Column(type="string")
*/
private $address;
/**
* #var string $comment
* #Column(type="string")
*/
private $comment;
/**
* #var integer $account_id
* #Column(type="integer")
*/
private $account_id;
/**
* #var integer $contact_id
* #Column(type="integer")
*/
private $contact_id;
/**
* #var string $created_at
* #Column(type="string")
*/
private $created_at;
/**
* #var contact_data $contact_data
* #Column(name="contact_data", type="integer", nullable=false)
* #OneToMany(targetEntity="Contact_Model_Contact", mappedBy="contact_data")
* #JoinColumn(name="contact_id", referencedColumnName="id")
*/
private $contact_data;
... (getters and setters)
Model Contact
<?php
/**
* #Table(name="contact_contacts")
* #Entity(repositoryClass="Contact_Model_ContactRepository")
*/
class Contact_Model_Contact {
/**
* #var integer $id
* #Id #Column(type="integer")
* #GeneratedValue
* #ManyToOne(targetEntity="Client_Model_Client", mappedBy="contact_data")
*/
private $id;
/**
* #var string $name
* #Column(type="string")
*/
private $name;
/**
* #var string $email
* #Column(type="string")
*/
private $email;
/**
* #var string $phone
* #Column(type="string")
*/
private $phone;
/**
* #var integer $address
* #Column(type="string")
*/
private $address;
/**
* #var string $comment
* #Column(type="string")
*/
private $comment;
/**
* #var string $created_at
* #Column(type="string")
*/
private $created_at;
/**
* #var integer $contact_id
* #Column(type="string")
*/
private $contact_id;
The query
$qb = $this->_em->createQueryBuilder()
->select('i, o')
->from('Client_Model_Client', 'i')
->join('i.Contact_Model_Contact', 'o');
$query = $qb->getQuery();
$roles = $query->getResult();
Zend_Debug::dump($roles); die;
What am I doing wrong?
How should it work?
You should be doing this:
$qb = $this->_em->createQueryBuilder()
->select('i, o')
->from('Client_Model_Client', 'i')
->join('i.contact_data', 'o');
i want to use this:
$query = $this->_doctrine->createQueryBuilder()
->select('u')
->from('\Entities\Users', 'l')
->leftJoin('l.userentities', 'u')
->getQuery();
return $info = $query->getResult();
and my users entity is:
namespace Entities\Users;
/**
* #Entity
* #Table(name="users")
* #HasLifecycleCallbacks
*/
class Users extends \Entities\AbstractEntity
{
/**
* #Id #Column(name="userid", type="integer")
* #GeneratedValue(strategy="AUTO")
*/
protected $userid;
/** #Column(name="itemid", type="integer") */
protected $itemid;
}
and my user entities entity class contains:
namespace Entities\Users;
/**
* #Entity
* #Table(name="userentities")
* #HasLifecycleCallbacks
*/
class Userentities extends \Entities\AbstractEntity
{
/**
* #Id #Column(name="entityid", type="integer")
* #GeneratedValue(strategy="AUTO")
*/
protected $entityid;
/** #Column(name="userid", type="integer") */
protected $userid;
/** #Column(name="crb", type="string") */
protected $crb;
}
i tried put this into the entity but no joy
* #OneToMany(targetEntity="Users", inversedBy="userid")
* #JoinColumn(name="userid", referencedColumnName="userid")
1 user has many user entities..
and i get this error:
Error: Class Entities\Users has no association named Users
i just want to do a left join with users to usersentities..
how can i doa left join?
Try putting this annotation in your Userentities class for the $userid field:
/**
* #var Entities\Userentities
* #ManyToOne(targetEntity="Users", inversedBy="userentities", cascade={"persist"})
*/
private $userid;
and this annotation in your Users class with a new field called $userentities:
/**
* #var \Doctrine\Common\Collections\ArrayCollection
* #OneToMany(targetEntity="Userentities", mappedBy="userid", cascade={"persist", "remove"})
*/
private $userentities;
I am starting my first Zend Framework + Doctrine 2 project and I have a question. I use PostgreSQL 9 and Apache 2.2
I have the following entities (the names of the entities and attributes are just for this example):
<?php
namespace Xproject\Entities;
/**
* Entity1
* #Table()
* #Entity
*/
class Entity1
{
/***
* #var integer $ent1Code
* #Column(name="ent1Code", type="integer", length=4)
* #Id
* #GeneratedValue(strategy="IDENTITY")
*/
private $ent1Code;
/**
* #var decimal $att1
* #Column(name="att1", type="decimal")
*/
private $att1;
/**
* OWNING SIDE
* #var \Doctrine\Common\Collections\ArrayCollection
* #ManyToOne(targetEntity="Entity2", inversedBy="entity1")
* #JoinColumn(name="ent2Code", referencedColumnName="ent2Code")
*/
private $entity2;
/**
* UNIDIRECTIONAL
* #var \Doctrine\Common\Collections\ArrayCollection
* #ManyToOne(targetEntity="Entity3")
* #JoinColumn(name="ent3Code", referencedColumnName="ent3Code")
*/
private $entity3;
/**
* UNIDIRECTIONAL
* #var \Doctrine\Common\Collections\ArrayCollection
* #ManyToOne(targetEntity="Entity4")
* #JoinColumn(name="ent4Code", referencedColumnName="ent4Code")
*/
private $entity4;
public function __construct() {
$this->entity2 = new \Doctrine\Common\Collections\ArrayCollection();
$this->entity3 = new \Doctrine\Common\Collections\ArrayCollection();
$this->entity4 = new \Doctrine\Common\Collections\ArrayCollection();
}
public function getEnt1Code(){
return $this->ent1Code;
}
public function getAtt1(){
return $this->att1;
}
public function setAtt1($value){
$this->att1=$value;
}
public function addEntity2(Entity2 $value){
$value->addEntity1($this);
$this->entity2->add($value);
}
public function addEntity3(Entity3 $value){
$this->entity3->add($value);
}
public function addEntity4(Entity4 $value){
$this->entity4->add($value);
}
}
<?php
namespace Xproject\Entities;
/**
* Entity2
* #Table()
* #Entity
*/
class Entity2
{
/**
* #var integer $ent2Code
* #Column(name="ent2Code", type="integer", length=4)
* #Id
* #GeneratedValue(strategy="IDENTITY")
*/
private $ent2Code;
/**
* INVERSE SIDE
* #var entity1
* #OneToMany(targetEntity="Entity1", mappedBy="entity2")
*/
private $entity1;
public function __construct() {
$this->entity1 = new \Doctrine\Common\Collections\ArrayCollection();
}
public function getEnt2Code(){
return $this->ent2Code;
}
public function addEntity1(Entity1 $value){
$this->entity1->add($value);
}
}
<?php
namespace Xproject\Entities;
/**
* Entity3
* #Table()
* #Entity
*/
class Entity3
{
/**
* #var integer $ent3Code
* #Column(name="ent3Code", type="integer", length=4)
* #Id
* #GeneratedValue(strategy="IDENTITY")
*/
private $ent3Code;
/**
* #var string $att1
* #Column(name="att1", type="string", length=150)
*/
private $att1;
public function getEnt3Code(){
return $this->ent3Code;
}
public function getAtt1(){
return $this->att1;
}
public function setAtt1($value){
$this->att1=$value;
}
}
<?php
namespace Xproject\Entities;
/**
* Entity4
* #Table()
* #Entity
*/
class Entity4
{
/**
* #var integer $ent4Code
* #Column(name="ent4Code", type="integer", length=4)
* #Id
* #GeneratedValue(strategy="IDENTITY")
*/
private $ent4Code;
/**
* #var string $att1
* #Column(name="att1", type="string", length=150)
*/
private $att1;
public function getEnt4Code(){
return $this->ent4Code;
}
public function getAtt1(){
return $this->att1;
}
public function setAtt1($value){
$this->att1=$value;
}
}
Just to try if everything is working I use the following code in Xproject's indexController:
<?php
class IndexController extends Zend_Controller_Action
{
public function init()
{
$this->doctrine = Zend_Registry::get('doctrine');
$this->em = $this->doctrine->getEntityManager();
}
public function indexAction()
{
$ent2 = new Xproject\Entities\Entity2();
$this->em->persist($ent2);
$ent3 = new Xproject\Entities\Entity3();
$ent3->setAtt1('xyz');
$this->em->persist($ent3);
$ent4= new Xproject\Entities\Entity4();
$ent4->setAtt1('abc');
$this->em->persist($ent4);
//1st flush
$this->em->flush();
$ent1= new Xproject\Entities\Entity1();
$ent1->setAtt1(350.00);
$ent1->addEntity2(ent2);
$ent1->addEntity3(ent3);
$ent1->addEntity4(ent4);
$this->em->persist($ent1);
//2nd flush
//$this->em->flush();
}
}
The first flush works OK and everything is saved OK into the database, but if I use both the first and the second flush, the browser indicates an Application Error and $ent1 is not saved at all into the database.
Using a var_dump($ent1) I can see that the object $ent1 state is correct (att1 and all the collections are loaded OK).
Apache error log doesn't show any error or warning during the loading of this script.
I definitely think I am missing some important thing here related to the ArrayCollections and how they work when you flush them.
Am I missing something crucial?
Your relationships are all ManyToOne, so there should be no ArrayCollections involved.
Since there are no collections, you don't want to add stuff, you want to set stuff:
In Entity1:
public function setEntity2(Entity2 $entity2){
$this->entity2 = $entity2
return $this;
}
In your controller:
$entity1->setEntity2($entity2);
And that's it. Your calls like $this->entity2->add() are working, because you're initializing those properties as ArrayCollections. But doctrine is just ignoring them.
In other words, for a *ToOne relationship, the object properties are just the foreign entity type. Treat them like simple values, and set them via typical set*() mutator.