Doctrine: RuntimeException - Not all identifier properties can be found in the ResultSetMapping - doctrine-orm

I started using Doctrine and ran into trouble immediately. I have an entity defined as follows:
namespace AdminModule;
use Doctrine\ORM\Mapping as ORM;
/**
* #ORM\Entity
* #ORM\Table(name="admin_user")
*/
class User extends \Nette\Object
{
/**
* #ORM\Id
* #ORM\Column(type="string", name="guid")
* #var string
*/
protected $id;
/**
* #ORM\Column(type="string")
* #var string
*/
protected $username;
/**
* #ORM\Column(type="string")
* #var string
*/
protected $password;
/**
* #ORM\Column(type="string")
* #var string
*/
protected $email;
/**
* #ORM\Column(type="datetime")
* #var datetime
*/
protected $registered;
/**
* #ORM\Column(type="datetime")
* #var datetime
*/
protected $last_login;
}
If I call
$u = $this->em->getRepository('AdminModule\User')->createQueryBuilder()
->select('u.username, u.id')
->from('AdminModule\User', 'u');
I get the RuntimeException stating that identifier property "id" is missing. However, when I run the above code with getQuery() and execute() it, it returns the result I want.
Can you help me out? If more information is needed, just tell me. Thank you.

Related

How to implement multi user support using fos user bundle

I've been working on a multi users web application using symfony 3.4 framework with fos user bundle in order to easily manipulate users.
I've integrated the bundle and everything work fine except that the bundle features don't match my need when it comes to multi users through inheritance !
Is there any trick to implement the multi user inheritance in fos bundle ?
I've tried a lot of different tricks like changing the roles , changing the user model interface, using symfony groups but all of them seemed to be not working !
The thing that will solve [with an ugly way] my problem is to change the value of the discriminator column .
* #ORM\Table(name="fos_user")
* #ORM\InheritanceType("SINGLE_TABLE")
* #ORM\DiscriminatorColumn(name="typeutilisateur", type="string")
* #ORM\DiscriminatorMap({"Parent"="User","admin" =
"Administrateur","association"
="AsoociationsBundle\Entity\Association",
"Demandeurservice"="EldersStoryBundle\Entity\Demandeurservice",
"Formateur"="FormationBundle\Entity\Formateur"
,"Prestataire"="AnnonceEldersCareBundle\Entity\Prestataireservice"})
class User extends BaseUser
{
/**
* #ORM\Id
* #ORM\Column(type="integer")
* #ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* #var string
*
* #ORM\Column(name="nom", type="string", length=30, nullable=true)
*/
private $nom;
/**
* #var string
*
* #ORM\Column(name="prenom", type="string", length=30, nullable=true)
*/
private $prenom;
/**
* #var string
*
* #ORM\Column(name="adresse", type="string", length=50)
*/
private $adresse;
/**
* #var string
*
* #ORM\Column(name="telephone", type="integer")
*/
private $telephone;
/**
* #var string
*
* #ORM\Column(name="sexe", type="string", length=30, nullable=true)
*/
private $sexe;
/**
* #var \DateTime
*
* #ORM\Column(name="datecreation", type="datetime")
*/
private $datecreation;
/**
* #var string
*
* #ORM\Column(name="avatar", type="string", length=255)
*/
private $avatar;
/**
* #ORM\ManyToMany(targetEntity="AppBundle\Entity\Group")
* #ORM\JoinTable(name="fos_user_user_group",
* joinColumns={#ORM\JoinColumn(name="user_id", referencedColumnName="id")},
* inverseJoinColumns={#ORM\JoinColumn(name="group_id", referencedColumnName="id")}
* )
*/
protected $groups;
public function __construct()
{
parent::__construct();
}
}
/*This is the sub class*/
<?php
namespace EldersStoryBundle\Entity;
use AppBundle\Entity\User;
use Doctrine\ORM\Mapping as ORM;
/**
* Demandeurservice
*
* #ORM\Table(name="demandeurservice")
* #ORM\Entity(repositoryClass="EldersStoryBundle\
Repository\DemandeurserviceRepository")
*/
class Demandeurservice extends User
{
/**
* #var string
*
* #ORM\Column(name="typemaladie", type="string", length=50)
*/
private $typemaladie;
/**
* #var string
*
* #ORM\Column(name="descriptionmaladie", type="string", length=255)
*/
private $descriptionmaladie;
/**
* #var string
*
* #ORM\Column(name="etatmaladie", type="string", length=255)
*/
private $etatmaladie;
/**
* #var int
*
* #ORM\Column(name="pointelderly", type="integer")
*/
private $pointelderly;
}
Everytime i subscribe i get the row in the table but with a discriminator column value ="parent"
So is there any major way to get this done ? or at least to change the value of the discriminator column ?
Remove the DiscriminatorMap. If you don't create one, Doctrine will generate one automagically. So long as you don't go messing around with names of Entity objects (ie, change Person to Persona, or whatever) then that's your best bet. It's also more dynamic because if/when you add additional types, it will update it for you (when cache is removed).
See here, last bullet point quoted:
If no discriminator map is provided, then the map is generated automatically. The automatically generated discriminator map contains the lowercase short name of each class as key.

How to fix cascade dont work in inheritance

The persist method dont work in inheritance class,although I have set the property cascade in annotation (cascade="all").
/**
* #ORM\Entity
* #ORM\InheritanceType("JOINED")
* #ORM\DiscriminatorColumn(name="tipo", type="string")
* #ORM\DiscriminatorMap({"menu" = "Menu", "enquete" = "Enquete"})
*/
abstract class Widget{
/**
* #ORM\Id
*/
protected $id;
}
/**
* #ORM\Entity
*/
class Enquete extends Widget{
/**
* #var ArrayCollection
* #ORM\OneToMany(targetEntity="Admin\Model\Alternativa", mappedBy="enquete", cascade="all")
*/
protected $alternativas;
}
/**
* #ORM\Entity
*/
class Alternativa{
/**
* #ORM\ManyToOne(targetEntity="Admin\Model\Enquete", inversedBy="alternativas")
* #ORM\joinColumn(name="Enquete_id", referencedColumnName="id")
*/
protected $enquete;
}
I Use persist in cascade but dont work:
$enquete->addAlternativa(New Alternativa());
$entityManager->persist($enquete);
$entityManager->flush();
The result is the follow error:
SQLSTATE[23000]: Integrity constraint violation: 1048 Column 'Enquete_id' cannot be null

Doctrine 2 Composite Primary Keys as Foreign Key

I have ClassA mapped to the entity ClassB with ManyToOne relation (simple so far).
class ClassA{
/**
* #var string
* #ORM\Id
* #ORM\Column(name="keyA", type="string", length=255)
*/
private $keyA;
/**
* #var ClassB $classB
* #ORM\ManyToOne(targetEntity="ClassB", inversedBy="classAs")
* #ORM\JoinColumns({
* #ORM\JoinColumn(name="ClassB_keyB", referencedColumnName="keyB")
* })
*/
private $classB;
}
And this is the ClassB:
class ClassB{
/**
* #var string
* #ORM\Id
* #ORM\Column(name="keyB", type="string", length=255)
*/
private $keyB;
/**
*
* #var ClassC $classC
* #ORM\Id
* #ORM\ManyToOne(targetEntity="ClassC", inversedBy="classBs")
* #ORM\JoinColumns({
* #ORM\JoinColumn(name="ClassC_keyC", referencedColumnName="keyC")
* })
*/
private $classC;
/**
* #var ArrayCollection $classAs
* #ORM\OneToMany(targetEntity="ClassA", mappedBy="classB")
*/
private $classAs;
}
As you can notice the ClassB contains a composite primary key (2 entities and on column).
And this is the ClassC:
class ClassC{
/**
* #var string
* #ORM\Id
* #ORM\Column(name="keyC", type="string", length=255)
*/
private $keyC;
/**
* #var ArrayCollection $classBs
* #ORM\OneToMany(targetEntity="ClassB", mappedBy="classC")
*/
private $classBs;
}
Whene i try to display all entities of ClassA (using findAll()) I get this exception Missing value for primary key classC on ERP\................\ClassB
What am I missing here ?!
you have to create your own method at ClassARepository and add your join columns

Create an entity that will be used by many other entities (Doctrine 2)

How can I do this?
My Entities:
Product entity
/**
* #ORM\Entity
* #ORM\Table(name="products")
*/
class Product
{
/**
* #ORM\Id()
* #ORM\Column(name="id", type="integer")
* #ORM\GeneratedValue(strategy="AUTO")
* #var int
*/
private $id;
/**
* #ORM\Column(type="string", length=512)
* #var string
*/
private $name;
/**
* (??)
* #var ArrayCollection
*/
private $images;
}
Article entity
/**
* #ORM\Entity
* #ORM\Table(name="articles")
*/
class Article
{
/**
* #ORM\Id()
* #ORM\Column(name="id", type="integer")
* #ORM\GeneratedValue(strategy="AUTO")
* #var int
*/
private $id;
/**
* #ORM\Column(type="string", length=512)
* #var string
*/
private $title;
/**
* (??)
* #var ArrayCollection
*/
private $images;
}
Image entity
/**
* #ORM\Entity
* #ORM\Table(name="images")
*/
class Image
{
/**
* #ORM\Id()
* #ORM\Column(name="id", type="integer")
* #ORM\GeneratedValue(strategy="AUTO")
* #var int
*/
private $id;
/**
* #ORM\Column(type="string", length=512)
* #var string
*/
private $name;
/**
* #ORM\Column(type="string", length=1024)
* #var string
*/
private $path;
}
I don't know how to create a link tables with additional fields like the picture. Which association should I use? How to manage these relations in entities?
Usually when you need a many to many approach Doctrine let you define such behaviour with a simple annotation.
#ORM\ManyToMany(targetEntity="full_qualified_namespace")
#ORM\JoinTable(
name="game_schemas_players",
joinColumns={#ORM\JoinColumn(name="this_field_name", referencedColumnName="id")},
inverseJoinColumns={#ORM\JoinColumn(name="that_field_anem", referencedColumnName="id")}
)
This will instruct Doctrine to create a relation the current entity and the target entity.
But that's not your case. For what I can see from your model you need to add some field on the 'middle' entity.
Here what you may want to do:
class Product
{
[...]
/**
* #var ArrayCollection | ProductImage[]
*
* #ORM\OneToMany(targetEntity="ProductImage", mappedBy="product")
*/
private $productImages;
}
class Image
{
[...]
/**
* #var ArrayCollection | ProductImage[]
*
* #ORM\OneToMany(targetEntity="ProductImage", mappedBy="image")
*/
private $productImages;
}
as you can see as defined here either Product and Image have a oneToMany relation with a middle entity which will be named ProductImage**.
The last step will be to implement such entity:
class ProductImage
{
[...]
/**
* #var Image
*
* #ORM\ManyToOne(targetEntity="Image", mappedBy="image")
* #ORM\JoinColumn(name="image_id", referencedColumnName="id")
*/
private $image;
/**
* #var Product
*
* #ORM\ManyToOne(targetEntity="Product", mappedBy="product")
* #ORM\JoinColumn(name="product_id", referencedColumnName="id")
*/
private $product;
/**
* #ORM\Column(type="string", length=1024)
* #var string
*/
private $position;
}
The owning side of the relation both for Product and Image is still ProductImage.
As a side note in your entity is common practice to implement an add method in this fashion:
public function __contructor(){
$this->productImages = new ArrayCollection();
}
/**
* Add ProductImage
*
* #param ProductImage $productImage
* #return $this
*/
public function addDocument(ProductImage $productImage)
{
$productImage->addProductImage($productImage);
$this->documents->add($document);
return $this;
}
and then you can use such method with the following approach:
$product = new Product();
$image = new Image();
$productImage = new ProductImage($product,$image);
$product->addProductImage($productImage);
Don't forget to provide the usual setter method as Doctrine need them to initialize the entity.
Hope it helps, Regards.

Doctrine 2 Association Mapping (ManyToOne and OneToMany)

I am new with Doctrine2 and need some help.
I have 2 Entities: LocationEntity and RatingEntity
RatingEntity
<?php
use Doctrine\ORM\Mapping as ORM;
/**
* Rating
*
* #ORM\Entity
* #ORM\Table(name="`RATING`")
*/
class RatingEntity {
/**
*
* #var int
* #ORM\Id
* #ORM\Column(name="`ID`", type="integer", nullable=false)
* #ORM\GeneratedValue(strategy="SEQUENCE")
* #ORM\SequenceGenerator(sequenceName="RATING_ID_SEQ", initialValue=1, allocationSize=1)
*/
protected $id;
/**
*
* #var int
* #ORM\Column(name="`LOCATION_ID`", type="integer")
*/
protected $locationId;
/**
* #var LocationEntity
* #ORM\ManyToOne(targetEntity="LocationEntity", inversedBy="ratings")
* #ORM\JoinColumn(name="`LOCATION_ID`", referencedColumnName="`ID`")
*/
protected $location;
/**
* #return the $location
*/
public function getLocation() {
return $this->location;
}
/**
* #param field_type $location
*/
public function setLocation($location) {
$this->location = $location;
}
and LocationEntity
<?php
use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
/**
* Location
*
* #ORM\Entity
* #ORM\Table(name="`LOCATION`")
*/
class LocationEntity {
/**
*
* #var int
* #ORM\Id
* #ORM\Column(name="`ID`", type="integer", nullable=false)
* #ORM\GeneratedValue(strategy="SEQUENCE")
* #ORM\SequenceGenerator(sequenceName="LOCATION_ID_SEQ", initialValue=1, allocationSize=1)
*/
protected $id;
/**
*
* #var ArrayCollection
* #ORM\OneToMany(targetEntity="RatingEntity", mappedBy="location", cascade={"persist"}, fetch="LAZY")
*/
protected $ratings;
/**
* #return the $ratings
*/
public function getRatings() {
return $this->ratings;
}
/**
* #param \Doctrine\Common\Collections\ArrayCollection $ratings
*/
public function setRatings($ratings) {
$this->ratings = $ratings;
}
/**
* Never forget to initialize all your collections!
*/
public function __construct() {
$this->ratings = new ArrayCollection();
}
If I get locations, i get ratings for location as Array,
but if I want to get Rating and Location for it, I get NULL only in getLocation().
Can somebody help?
I don't think that you need the locationId property in your Rating entity as the column is already mapped using the location property. Try removing the locationId section and see if it doesn't work as expected.