Symfony2 building ManyToOne relationship in Entities - symfony

I have two entities in a OneToMany relationship, Perfil and IPerfil. Perfil can have several IPerfil's associated:
>
class Perfil
{
/**
* #var integer $id
*
* #ORM\Column(name="id_perfiles", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="SEQUENCE")
* #ORM\SequenceGenerator(sequenceName="P360.perfiles_seq")
* #ORM\OneToMany(targetEntity="IPerfil", mappedBy="id")
*/
private $id;
And the other one:
>
class IPerfil
{
/**
* #var integer $id
* #ORM\ManyToOne(targetEntity="Perfil")
* #ORM\JoinColumn(name="id_perfiles", referencedColumnName="id_perfiles", onDelete="CASCADE")
*/
protected $id;
I'm able to lazyload from IPerfil to Perfil, but not in the other direction (from Perfil to IPerfil), but if I can't do any DQL over IPerfil or createQueryBuilder()->setPameter... Symfony will always return an error like this:
[Semantical Error] line 0, col 9 near 'id_perfiles FROM': Error: Invalid PathExpression. Must be a StateFieldPathExpression.
If I define the field Id with an
#ORM\Column(name="id_perfiles", type="integer")
Then I'm able to build DQL's with the entity, but the relationship won't work anymore.
I'm lost around here... It seems I'm missing something in the relationship definition, but have no clue.
Thanks in advance for any tip.
EDIT
If I use:
$entities=$em->getRepository('usuariosBundle:IPerfil')->findAll(array());
It doen'st gives an error, but I need to filter and order the results.
$entities=$em->getRepository('usuariosBundle:IPerfil')->findBy(array(),array('id' => 'asc', 'descripcion' => 'asc'));
Unrecognized field: id
$query=$em->getRepository('usuariosBundle:IPerfil')->createQueryBuilder('p')
->orderBy('id', 'ASC')
->getQuery();
$entities = $query->getResult();
*[Semantical Error] line 0, col 60 near 'id ASC': Error: 'id' is not defined. *
$entities = $this->get('doctrine')->getEntityManager()->createQuery('SELECT p.id FROM usuariosBundle:IPerfil p ')->getResult();
[Semantical Error] line 0, col 9 near 'id FROM usuariosBundle:IPerfil': Error: Invalid PathExpression. Must be a StateFieldPathExpression.

Use attribute name of class, no column name on dql => 'id'
->orderBy('p.id', 'ASC') and ->createQuery('SELECT p FROM usuariosBundle:IPerfil p ')->getResult(), the name of bundle is usuarios os Usuarios ?

If it is useful to anyone, I finally created a non-persistent attribute in the Perfil entity to attach the the relationship and a collection of IPerfil's there:
/**
* #ORM\OneToMany(targetEntity="IPerfil", mappedBy="id")
*/
private $desc;
Need to declare it as a ArrayCollection:
public function __construct()
{
$this->desc = new \Doctrine\Common\Collections\ArrayCollection();
}
And now I'm able to lazy load in the right direction and do any necessary operation. I suppouse Doctrine couldnt load the collection into id, as it wasn't declared as a collection and it's the ID field.

Related

symfony doctrine one-to-many entity setup

I'm trying to get my head around the entity annotations for a doctrine one to many relationship.
For example, if table_one (T1) is:
email_address (string)
and table_two (T2) is
userid_email (string)
entry (int)
(email_address.table_one = userid_email.table_two) and there are multiple entries in table_two i.e
userid_email=test#email.com,entry=5;
userid_email=test#email.com,entry=6
Do I create the annotation for the T1 Entity
/**
* #ORM\ManyToMany(targetEntity="T1")
* #ORM\JoinTable(name="table_two",
* joinColumns={#ORM\JoinColumn(name="userid", referencedColumnName="userid_email")}
* )
*/
protected entries;
public function __construct()
{
$this->entries = new ArrayCollection();
}
And then in a createQuery I query on T1 :
$query = $em->createQuery('
SELECT u.email, u.entries
FROM AppBundle:T1 u
WHERE u.email = :an_email_address');
For the above query I would always get this error :
Error: Invalid PathExpression. Must be a StateFieldPathExpression
Is there something I am setting up improperly for the relationship?
Your configuration seems to be wrong, try something like:
/**
* #ORM\ManyToMany(targetEntity="T1")
* #ORM\joinColumn={#ORM\JoinColumn(name="userid", referencedColumnName="userid_email")}
* )
*/

Doctrine n:m relation Undefined index: joinColumns in BasicEntityPersister.php

My question is strongly related to this one Undefined index: inverseJoinColumns while trying to define ManyToMany relationship between two entities
I am trying to find all the books which have no section. ->findBy(array("section"=>null)
Here is my Entity config:
EditedBooks
/**
* #var \Doctrine\Common\Collections\Collection
*
* #ORM\ManyToMany(targetEntity="Sections", inversedBy="editedBook")
* #ORM\JoinTable(name="edited_book_has_section",
* joinColumns={
* #ORM\JoinColumn(name="edited_book_id", referencedColumnName="id")
* },
* inverseJoinColumns={
* #ORM\JoinColumn(name="section_id", referencedColumnName="id")
* }
* )
*/
private $section;
Here is my Entity config:
Sections
/**
* Bidirectional (INVERSE SIDE)
*
* #ORM\ManyToMany(targetEntity="EditedBooks", mappedBy="section")
*/
private $editedBook;
The Error that I am getting
Undefined index: joinColumns in BasicEntityPersister.php
I tryied it also with only
/**
* #var \Doctrine\Common\Collections\Collection
*
* #ORM\ManyToMany(targetEntity="Sections", inversedBy="editedBook")
* #ORM\JoinTable(name="edited_book_has_section")
*/
or switching the definition but then I receive this error
You cannot search for the association field '\Entity\EditedBooks#section', because it is the inverse side of an association. Find methods only work on owning side associations.
Workaround:
Today I tried to fix my problem with the querybuilder in my editedBooksRepository
$query = $qb->select('books')
->from('Bundle:EditedBooks', 'books')
->leftJoin('books.section', 'sec')
->addSelect('COUNT(sec.id) AS sec_count')
->andWhere('sec_count = 0');
But I receved the following error:
An exception occurred while executing 'SELECT e0_.id AS id0, e0_.doi
AS doi1, e0_.isbn_print AS isbn_print2, e0_.isbn_electronic AS
isbn_electronic3, e0_.publication_date AS publication_date4,
e0_.price_print AS price_print5, e0_.price_electronic AS
price_electronic6, e0_.summary AS summary7, e0_.title AS title8,
e0_.ongoing AS ongoing9, e0_.pages AS pages10, e0_.illustrations AS
illustrations11, e0_.entry_date AS entry_date12, e0_.google_id AS
google_id13, e0_.specialIssue_comment AS specialIssue_comment14,
e0_.deleted AS deleted15, e0_.specialIssue_id AS specialIssue_id16,
COUNT(s1_.id) AS sclr17, e0_.book_series_id AS book_series_id18,
e0_.copyright_id AS copyright_id19, e0_.publisher_id AS publisher_id20
FROM edited_books e0_ LEFT JOIN edited_book_has_section e2_ ON e0_.id
= e2_.editedbooks_id LEFT JOIN sections s1_ ON s1_.id = e2_.sections_id WHERE sclr17 = 0':
SQLSTATE[42S22]: Column not found: 1054 Unknown column 'sclr17' in
'where clause'
but to me it seems like sclr17 exists, am I missing something?
The ugly Workaround
I know it is not the right thing to do but sometimes a man has to to what a man has to do:
$noSection = new Sections();
$noSection->setTitle("Sectionless");
//add all the books
$noSection->setEditedBook(new ArrayCollection($books));
//remove the assigned ones
foreach($sections as $section){
$sBooks = $section->getEditedBook();
foreach($sBooks as $b){
$noSection->removeEditedBook($b);
}
}
With the dirty fix it is now working but I am glad for any other solution.
Here is a working example
class Audio
{
/**
* #ORM\ManyToMany(targetEntity="Acme\MyBundle\Entity\Groupe",inversedBy="audios")
*/
private $groupes;
class Groupe
{
/**
* #ORM\ManyToMany(targetEntity="Acme\MyBundle\Entity\Audio",mappedBy="groupes")
*/
private $audios;
Notice how the mappedby and inversedby, as well at the attributes have an "s" at the end. (Groupe => private $groupe s ). Maybe it will help you
Can't you just check with null?
$query = $qb->select('books')
->from('Bundle:EditedBooks', 'books')
->leftJoin('books.section', 'sec')
->where('sec IS NULL');

Access to inherit class attribute from DQL in Symfony2

I have an abstract class Product and inherited class ProductWithRecurrency:
/**
* #ORM\Table(name= "product")
* #ORM\Entity(repositoryClass="Acme\StoreBundle\Entity\Repositories\ProductRepository")
* #ORM\InheritanceType("JOINED")
* #ORM\DiscriminatorColumn(name="product_kind_id", type="integer")
* #ORM\DiscriminatorMap({"1" = "ProductFoo", "2" = "ProductWithRecurring"})
*/
abstract class Product
{
}
/**
*
* #ORM\Table(name="product_with_recurring")
* #ORM\Entity( repositoryClass ="Acme\StoreBundle\Entity\Repositories\ProductRepository")
*/
class ProductWithRecurring extends Product
{
/**
* #var Recurring $recurring
*
* #ORM\JoinColumn(name="recurring_id", referencedColumnName="id", nullable=false)
*/
protected $recurring;
}
I need to get some mixed Products and have "Recurring" Entity information when Product is instance of ProductWithRecurring. I have a method in ProductRepository with this dql:
$dql = "SELECT p product
FROM Acme\StoreBundle\Entity\Product p
LEFT JOIN p.recurring rc
WHERE p.some_conditions";
Obviously get this exception:
[Semantical Error] line 0, col 1182 near 'rc
': Error: Class Acme\StoreBundle\Entity\Product has no association named recurring
Do I should add complexity to query or I have a conceptual error? (I'm no expert in Symfony and less in Doctrine).
There may be errors in the code, I've simplified it to isolate the problem.
My english is not so good, I hope you understand me, thanks!
You should be able to access all of the Product atributes in Product ProductWithRecurring.
Using code below does not work? I do not quite understand what you'd like to get as a result
$dql = "SELECT p
FROM Acme\StoreBundle\Entity\ProductWithRecurring p
WHERE p.some_conditions";

Symfony2 and Doctrine - Error: Invalid PathExpression. Must be a StateFieldPathExpression

I have an entity that looks like this:
/**
* #Gedmo\Tree(type="nested")
* #ORM\Table(name="categories")
* #ORM\Entity()
*/
class Category extends BaseCategory
{
/**
* #ORM\OneToMany(targetEntity="Category", mappedBy="parent")
*/
protected $children;
/**
* #Gedmo\TreeParent
* #ORM\ManyToOne(targetEntity="Category", inversedBy="children")
* #ORM\JoinColumn(name="parent_id", referencedColumnName="id", onDelete="SET NULL")
*/
protected $parent;
}
and I am trying to run a query like this:
$qb = $this->em->createQueryBuilder()
->select('c.parent')
->from('Category', 'c');
$result = $qb->getQuery()->getArrayResult();
However, I am getting the following error:
[Semantical Error] ... Error: Invalid PathExpression. Must be a StateFieldPathExpression.
How can I select the parent_id field from my table. I have tried a bunch of variations and even if I do something like this:
$qb = $this->em->createQueryBuilder()
->select('c')
->from('Category', 'c');
I get all fields in the table except for the parent_id. This seems like Doctrine is getting in the way. How can I query for this parent_id field? or better yet how can I get all fields in the table including the parent_id
You can use the currently undocumented IDENTITY function to select the FK IDs in a query:
SELECT IDENTITY(c.parent) ...
Solution using createQueryBuilder:
$query->SELECT('pa.id')
->from('Category', 'ca');
$query->join('ca.parent', 'pa');
$result = $query->getQuery()->getArrayResult();
You are selecting an object that is not joined.
Like said in another answer, you have to do something like :
qb->innerJoin("c.parent", "p")
You can change it like this:
->select(array('i.id','identity(i.parent) parent','i.nom'))

ManyToMany bidirectional [Semantical Error] User has no association named service

I have two netities user & service and the join table user_service generated by doctrine, i tried to add a manytomany relatioship here is the annotations that i added :
Entity User side :
/**
* #ORM\ManyToMany(targetEntity="Service", inversedBy="users")
* #ORM\JoinTable(name="user_service",
* joinColumns={#ORM\JoinColumn(name="user_id", referencedColumnName="id")},
* inverseJoinColumns={#ORM\JoinColumn(name="service_id", referencedColumnName="id")}
* )
*/
protected $services;
Entity Service side :
/**
* #ORM\ManyToMany(targetEntity="User", mappedBy="services")
*/
protected $users;
Everything seems to work fine, but when i make this request :
$query = $em->createQuery(
'SELECT u
FROM ApplicationFrontBundle:User u
JOIN u.service s
WHERE u.id = :id
'
)->setParameters(array('id'=> $id));
$services = $query->getArrayResult();
I have this error :
[Semantical Error] line 0, col 91 near 's
': Error: Class Application\FrontBundle\Entity\User has no association named service
But when i do it by the objects it works, the problem is that it executes a lot of requests
Because you named it serviceSSS?
$query = $em->createQuery(
'SELECT u
FROM ApplicationFrontBundle:User u
JOIN u.services s
WHERE u.id = :id
'
)->setParameters(array('id'=> $id));
$services = $query->getArrayResult();

Resources