Doctrine ORM join user group on parent row - doctrine-orm

Is it possible to make #ORM\OneToOne join where parent is null?
Currently im using #ORM\OneToMany to get all rows and filtering to find only one parnent (where parent is NULL) entity

Yes it is possible with the nullable=true annotation :
<?php
/**
* #ORM\JoinColumn(name="commentary_id", nullable=true)
* #ORM\OneToOne(targetEntity="App\Entity\Commentary")
*/
private $commentary;
All the documentation is here : https://www.doctrine-project.org/projects/doctrine-orm/en/2.7/reference/annotations-reference.html#joincolumn

Related

Target non-existing entity in querybuilder (ManyToMany relationship)

I can't seem to target the JoinTable 'product_features' in a query builder:
/**
* #ORM\ManyToMany(targetEntity="AttributeOption", cascade={"persist"})
* #ORM\JoinTable(name="product_features",
* joinColumns={#ORM\JoinColumn(name="product_id", referencedColumnName="id")},
* inverseJoinColumns={#ORM\JoinColumn(name="attribute_option_id", referencedColumnName="id")}
* )
*/
protected $features;
I did discover that you can join a non-related table but you need to call it by the entity in order to do so. Am I right? There is no entity since it's just a table generated by the ManyToMany mapping.
This is what I've tried but it does target the targetEntity 'AttributeOption':
$query
->innerJoin('p.features', 'f')
->setParameter('filters', $filters)
->andWhere('f.id IN (:filters)');
I really need the product_features table in my query. Please, help me out!
Thanks in advance!
Regards,
Demi

Doctrine2 - Annotations: eager load (join) vs. nullable column (ManyToOne)

I have this:
/**
* #ManyToOne(targetEntity="TblCity",fetch="EAGER",cascade={"persist"})
* #JoinColumn(name="tblCity",referencedColumnName="Id")
*/
and it creates the correct JOIN for table tblCity in sql and TblCity entity is plugged in my parent entity - aka "Eager-Load"
Pseudo result:
PersonEntity: {
Id: 1
...
CityEntity: {
Id: 1
...
}
}
but, this column NEEDS to be nullable
(if it runs into a "missing" foreign id it complains about missing proxy files for TblCity).
So it has to look like this:
/**
* #Column(nullable=true)
* #ManyToOne(targetEntity="TblCity",fetch="EAGER",cascade={"persist"})
* #JoinColumn(name="tblCity",referencedColumnName="Id")
*/
and poff there goes the "Eager-Load"
The generated sql is missing the JOIN of table tblCity and the column contains only the id and not the entity for TblCity
Pseudo result:
PersonEntity: {
Id: 1
...
CityEntity: 1 (as integer)
}
What am I doing wrong?
PS: I CAN'T use createQuery or such things, so please no solutions involving that
The doctrine #JoinColumn annotation has an optiobal attribute nullable which defaults to true. Read more on this here in the documentation: 21.2.15. #JoinColumn
So the proper way to declare nullable for the join column is:
#JoinColumn(name="tblCity",referencedColumnName="Id", nullable=true)
But nullable is true by default so you don't really need it...
My guess would be that your #Column annotation is overruling the whole #ManyToOne annotation in your case. That is why you get only an id and no TblCity entity.

Doctrine2 migrations rename index for foreign keys

I have problem with renaming indexes in doctrine:migrations:diff. Everytime when i ran this command, doctrine created sql queries to rename existing index in database. Is there any way to prevent this behaviour?
Full description:
we have big(about 2 hundres tables) old database on Oracle. There are naming conventions for constraint and indexes, for example:
we have table RANDOM_KEY and USER, foreign key (many to one) from RANDOM_KEY to USER, so coinstraint has name FK_RANDOM_KEY_USER and relevant index is FK_RANDOM_KEY_USER_I.
Entity declaration:
/**
* #ORM\Table(name="RANDOM_KEY")
* #ORM\Entity
*/
class RandomKey {
...
Relations declaration:
/**
* #var \User
*
* #ORM\ManyToOne(targetEntity="\User")
* #ORM\JoinColumns({
* #ORM\JoinColumn(name="USER_ID", referencedColumnName="USER_ID")
* })
*/
private $user;
Result of migrations:diff commad is:
$this->addSql("ALTER INDEX FK_RANDOM_KEY_USER_I RENAME TO IDX_C54F7889A0666B6F");
I looked into depth of doctrine, tried some debugging. Between indexes are no other differences, only name. Also I tried add indexes definition to #ORM/Table. Is there way to prevent index renaming?
Relevant composer data:
"symfony/symfony": "2.4.*",
"doctrine/orm": "2.5.*",
"doctrine/dbal": "2.5.*",
"doctrine/migrations": "1.0.*#dev",
"doctrine/doctrine-bundle": "1.2.*",
"doctrine/doctrine-migrations-bundle": "2.1.*#dev",

createNativeQuery - oci8 returns empty array

on a very simple entity :
class Users {
/**
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
* #ORM\Column(type="integer")
*/
protected $userid;
/** #ORM\Column(type="string") */
protected $username;
}[...]
while trying to do a native query
$rsm = new \Doctrine\ORM\Query\ResultSetMapping;
$rsm->addEntityResult('Application\Entity\Users', 'u');
$rsm->addFieldResult('u', 'test', 'username');
$rsm->addFieldResult('u', 'userid', 'userid');
$q = $objectManager->createNativeQuery('SELECT u.username as test, u.userid from users u where u.userid=17',$rsm);
$result = $result->getResult();
$result returns an empty array with oracle (oci8 driver and pdo).
With MySQL, all is ok. The databases are exactly the same between Oracle and MySQL, same tables, same columns.
The table 'users' is not empty, because when using DQL, it works. Works too when using addRootEntityFromClassMetadata() whith a native query.
It seems that the problem occurs only with oci8+addEntityResult().
Any idea ?
Thanks by advance.
Found it in the manual.
ResultSetMapping#addFieldResult();
The first parameter is the alias of the entity result to which the field result will belong. The second parameter is the name of the column in the SQL result set. Note that this name is case sensitive, i.e. if you use a native query against Oracle it must be all uppercase. The third parameter is the name of the field on the entity result identified by $alias into which the value of the column should be set.
$rsm->addFieldResult('u', 'TEST', 'username');
$rsm->addFieldResult('u', 'USERID', 'userid');

Doctrine 2 query missing part of inner join

I'm using Doctrine 2 to try and do a query with an inner join. I have a Site entity and a Page entity. Each Site can have many pages and each page can only belong to one site. I have a site_id foreign key in my pages table rows. In my Site entity, I've created a OneToMany assocatiion where the target entity is my Page entity and the mappedBy is set to Site.
/**
* #var \Doctrine\Common\Collections\ArrayCollection
* #OneToMany(targetEntity="Page", mappedBy="Site", cascade={"persist", "remove"})
*/
private $pages;
In my Page entity, I have a ManyToOne association where the target entity is set to Site.
/**
* #var App\Entity\Site
* #ManyToOne(targetEntity="Site")
*/
private $site;
Here is my query builder statement where I'm passing a specific Site id:
$qb = $this->_em->createQueryBuilder();
$qb->select('s')
->from('App\Entity\Site', 's')
->innerJoin('s.pages', 'p')
->where('s.id = :id')
->setParameter('id', $id);
and here is the actual SQL I get back:
SELECT s0_.id AS id0, s0_.domain AS domain1 FROM sites s0_ INNER JOIN WHERE s0_.id = ?
See how the INNER JOIN information is completely missing? Am I doing something wrong here or is this a problem with Doctrine 2?
You need to explicitly tell Doctrine to fetch those columns:
$qb->select('s', 'p')
->form(...)
->join(...)
Figured it out. My mappedBy statement was incorrect in Site entity. I was pointing at "Site" when it should have been "site".