Doctrine/dflydev - OneToMany associated ID - php

I got this error from my UserRepository:
[Semantical Error] line 0, col 51 near 'h': Error: Class DokMngr\Entity\User has no association named id
I understand that the error comes from the missing declaration inside my user entity. I can not find a correct syntax when a field is both a generated id and a OneToMany association.
Hope somebody can help me to solve my problem or at least explain why I can't use an id as an association.
class UserRepository extends EntityRepository
{
public function findAllwithHistoryCount() {
$qb = $this->createQueryBuilder('u')
->leftJoin('u.id', 'h');
return $qb->getQuery()->getResult();
}
}
/**
* #Entity(repositoryClass="DokMngr\Repository\UserRepository")
* #Table(name="users")
*/
class User implements UserInterface
{
/**
* #Id
* #Column(type="integer")
* #GeneratedValue
*/
protected $id;
}
/**
* #Entity(repositoryClass="DokMngr\Repository\HistoryRepository")
* #Table(name="history")
*/
class History
{
/**
* #Id
* #Column(type="integer")
* #GeneratedValue
*/
protected $id;
/**
* #ManyToOne(targetEntity="User", inversedBy="id")
* #JoinColumn(name="user", referencedColumnName="id")
*/
protected $user;
}

Thanks to Olibiaz I found my error in reasoning.
I thought the whole time that I have to create an association between User.id and History.user like inside the database.
But instead I have to create a new field histories in my User entity. (which exactly not exist inside the database)
So here's the corrected entities:
User
use Doctrine\Common\Collections\ArrayCollection;
/**
* #Entity(repositoryClass="DokMngr\Repository\UserRepository")
* #Table(name="users")
*/
class User implements UserInterface
{
/**
* #Id
* #Column(type="integer")
* #GeneratedValue
*/
protected $id;
/**
* #OneToMany(targetEntity="History", mappedBy="user")
*/
private $histories;
}
History
/**
* #Entity(repositoryClass="DokMngr\Repository\HistoryRepository")
* #Table(name="history")
*/
class History
{
/**
* #Id
* #Column(type="integer")
* #GeneratedValue
*/
protected $id;
/**
* #ManyToOne(targetEntity="User", inversedBy="histories")
* #JoinColumn(name="user", referencedColumnName="id")
*/
protected $user;
}

Related

Doctrine 2 OneToOne from PFK of another OneToOne association

I have one question. I'm using Doctrine 2.0 and i want to know if is possible to made OneToOne association by using PFK created by another OneToOne assotiation as you can see on the picture below.
My code looks like this:
User class:
/**
* #ORM\Entity()
*/
class User extends \Kdyby\Doctrine\Entities\IdentifiedEntity
{
/**
* #ORM\OneToOne(targetEntity="AllianceMember", mappedBy="user")
* var AllianceMember
*/
protected $allianceMembership;
}
AllianceMember class:
/**
* #ORM\Entity()
*/
class AllianceMember extends \Kdyby\Doctrine\Entities\BaseEntity
{
/**
* #ORM\Id
* #ORM\OneToOne(targetEntity="User", inversedBy="allianceMembership")
* #ORM\JoinColumn(name="user_id", referencedColumnName="id", nullable=false)
* #var User
*/
protected $user;
/**
* #ORM\OneToOne(targetEntity="AllianceRole", mappedBy="allianceMember")
* var AllianceRole
*/
protected $role;
AllianceRole class:
/**
*
* #ORM\Entity()
*/
class AllianceRole extends \Kdyby\Doctrine\Entities\BaseEntity
{
/**
* #ORM\Id
* #ORM\OneToOne(targetEntity="AllianceMember", inversedBy="role")
* #ORM\JoinColumn(name="role_id", referencedColumnName="user_id", nullable=false)
* #var AllianceMember
*/
protected $allianceMember;
}
I'm getting this error, when I'm trying to get instance of User entity:
The column user_id must be mapped to a field in class App\Entity\AllianceMember since it is referenced by a join column of another class.
Is it even possible?
Thanks.
Yes, using mapped entities for your #Id has been possible since doctrine 2.1 see Primary key and foreign key at the same time with doctrine 2
I think you simply need to remove some of your JoinColumn statements. Since #user is already designated as your #Id, it isn't necessary to specify user_id as the JoinColumn:
/**
* #ORM\Entity()
*/
class AllianceMember extends \Kdyby\Doctrine\Entities\BaseEntity
{
/**
* #ORM\Id
* #ORM\OneToOne(targetEntity="User", inversedBy="allianceMembership")
* #var User
*/
protected $user;
/**
* #ORM\OneToOne(targetEntity="AllianceRole", mappedBy="allianceMember")
* var AllianceRole
*/
protected $role;
and
/**
*
* #ORM\Entity()
*/
class AllianceRole extends \Kdyby\Doctrine\Entities\BaseEntity
{
/**
* #ORM\Id
* #ORM\OneToOne(targetEntity="AllianceMember", inversedBy="role")
* #var AllianceMember
*/
protected $allianceMember;
}
The id of the AllianceMember is the user_id, and the id of the AllianceRole is the id of the AllianceMember, which is user_id.

Doctrine/Symfony - I have some errors. Something wrong with my relations

I always get an exception with my entities. I tried to play with them. I checked on google which relation is the most appropriate for my entities... But I couldn't find the best configuration.
I'm making a website where you can create some albums.
A user can have multiple albums.So I have an entity Album and I have inside a user property :
/**
* Album
*
* #ORM\Table(name="album")
* #ORM\Entity(repositoryClass="Moodress\Bundle\AlbumBundle\Entity\AlbumRepository")
*/
class Album
{
/**
* #var integer
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
** #ORM\ManyToOne(targetEntity="Moodress\Bundle\UserBundle\Entity\User")
** #ORM\JoinColumn(nullable=false)
*/
private $user;
/**
* #var string
*
* #ORM\Column(name="name", type="string", length=255)
*/
private $name;
/**
* #var \DateTime
*
* #ORM\Column(name="creationDate", type="datetime")
*/
private $creationDate;
/**
* #var \DateTime
*
* #ORM\Column(name="modificationDate", type="datetime")
*/
private $modificationDate;
/**
* #ORM\OneToMany(targetEntity="Moodress\Bundle\AlbumBundle\Entity\Picture", cascade={"persist"}, mappedBy="album")
*/
private $pictures;
/**
* Constructor
*/
public function __construct()
{
$this->creationDate = new \Datetime();
$this->modificationDate = new \Datetime();
}
// Get and set
}
However, When a user subscribe on the website, I create a default album called Upload that I want to keep in the user class.
This is what I tried to do :
/**
* User
*
* #ORM\Entity
* #ORM\Table(name="user")
*/
class User extends BaseUser
{
/**
* #ORM\Id
* #ORM\Column(type="integer")
* #ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* #ORM\OneToOne(targetEntity="Moodress\Bundle\AlbumBundle\Entity\Album", cascade={"persist"})
*/
protected $albumUpload;
// Get and set
}
I have this error :
Undefined index: album in /Users/Sandro/sites/moodress-website/Symfony/vendor/doctrine/orm/lib/Doctrine/ORM/Persisters/BasicEntityPersister.php line 1608. This error appears directly when I serialize any entity that has a user object...
The error is caused by the association annotation of the $albumUpload property in the User class.
Doctrine assumes that you have a $album property in your Album entity when you use a #ORM\OneToOne(targetEntity="Moodress\Bundle\AlbumBundle\Entity\Album") association in your User entity.
Try
/**
** #ORM\ManyToOne(targetEntity="Moodress\Bundle\UserBundle\Entity\User", inversedBy="albums")
** #ORM\JoinColumn(nullable=false)
*/
private $user;
in your Album entity and
/**
* #ORM\OneToMany(targetEntity="Moodress\Bundle\AlbumBundle\Entity\Album", mappedBy="user", cascade={"persist"})
*/
protected $albums;
in your User entity. In addition please add $this->albums = new ArrayCollection() to User::__construct().
Now if you want to add and keep a default album for users you should implement this somewhere in your business logic. You could figure out a way to identify the default album in your collection of albums and prevent deletion especially for this item.
Hope this helps.
My error:
'Undefined index: album'
results from this annotation in the Album class.
/**
* #ORM\OneToMany(
* targetEntity="Moodress\Bundle\AlbumBundle\Entity\Picture",
* cascade={"persist"},
* mappedBy="album"
* )
*/
I have set mappedBy to album but there is no $album property in my Picture class.
I did add this to my Picture class and clear my cache.
/**
* #ORM\ManyToOne(
* targetEntity="Moodress\Bundle\AlbumBundle\Entity\Album",
* inversedBy="pictures"
* )
*/
protected $album;
It solved my problem

Doctrine 2 - How to have an association class with a mapped superclass?

I'm having trouble with a Doctrine 2 mapped superclass, to define a ManyToMany Relation.
My code is :
use Doctrine\Common\Collections\ArrayCollection;
/** #MappedSuperclass */
abstract class MyAbstractClassA
{
/**
* #Id
* #GeneratedValue
* #Column(type="integer")
* #var int
*/
protected $id;
/**
* #ManyToMany(targetEntity="MyClassE")
* #var MyClassE[]
*/
protected $my_class_es;
// ... Other fields and methods
}
/** #Entity() */
class MyConcreteClassAa extends MyAbstractClassA
{
/**
* #Column(type="string")
* #var string
*/
public $aa_param;
// ... Other fields and methods
}
/** #Entity() */
class MyConcreteClassAb extends MyAbstractClassA
{
/**
* #Column(type="string")
* #var string
*/
public $ab_param;
// ... Other fields and methods
}
/** #Entity() */
class MyClassE
{
/**
* #Id
* #Column(type="integer")
* #var int
*/
protected $id;
/**
* #Column(type="string")
* #var string
*/
protected $e_param;
/**
* #ManyToOne(targetEntity="MyClassF")
* #var MyClassF
*/
protected $my_class_f;
// ... Other fields and methods
}
/** #Entity() */
class MyClassF
{
/**
* #Id
* #Column(type="integer")
* #var int
*/
protected $id;
// ... Other fields and methods
}
So here is the schema of what i have : http://pix.toile-libre.org/upload/original/1385651287.png
And there is what i want : http://pix.toile-libre.org/upload/original/1385651300.png
I don't know how to obtain this result, could someone tell me if it's possible ?
Thank you for helping me.

Doctrine Orm lazy load with group by

I have the following situation:
/**
* #Entity
* #Table(name="users")
*/
class Users{
/**
*
* #Id #Column(type="integer")
* #GeneratedValue
*/
protected $id_user;
/**
* #OneToMany(targetEntity="Items",mappedBy="user")
*/
private $items;
//this method sould return distinct items by name or group by name
public function getItems(){
return $this->items;
}
}
/**
* #Entity
* #Table(name="items")
*/
class Items{
/**
*
* #Id #Column(type="integer")
* #GeneratedValue
*/
protected $id_item;
/**
*
* #Id #Column(type="string")
*/
protected $name;
/**
* #ManyToOne(targetEntity="User",inversedBy="items")
* #JoinColumn(name="id_user", referencedColumnName="id_user" ,onDelete="CASCADE")
*/
protected $user;
}
In my view i send an $UserEntity, my problem is that i want to display only items that have unique name.
So If i do $items=$userEntity->getItems(); i receive all user items, not only unique one.
How can i solve this situation?
Thanks
select distinct with DQL should do the trick

Triple split mapping issue with Doctrine2

I'm encountering a strange problem using Doctrine2.
I'm getting the following error:
doctrine orm:validate-schema
[Mapping] FAIL - The entity-class 'EmailVerification' mapping is invalid:
* The referenced column name 'id' does not have a corresponding field with this
column name on the class 'OurUsers'.
[Database] OK - The database schema is in sync with the mapping files.
My scenario is as follows:
I have 3 tables sharing a primary key.
Table Auth which holds user_id PK.
Table OurUsers for which Auth.user_id is shared PK.
Table EmailVerification for which OurUsers.user_id is shared PK.
I also have NotOurUsers - hence the split.
Entities are declared as follows:
/**
* #Entity
* #Table(name="auth")
*/
class Auth {
/** #Id #Column(type="integer", name="user_id") #GeneratedValue #var int */
private $id;
/* ... */
}
/**
* #Entity
* #Table(name="our_users")
*/
class OurUsers {
/**
* #Id
* #OneToOne(targetEntity="Auth")
* #JoinColumn(nullable=false, name="user_id", referencedColumnName="user_id")
* #var Auth
*/
private $id;
/* ... */
}
/**
* #Entity
* #Table(name="email_verification")
*/
class EmailVerification {
/**
* #Id
* #OneToOne(targetEntity="OurUsers")
* #JoinColumn(nullable=false, name="user_id", referencedColumnName="user_id")
* #var OurUsers
*/
private $id;
/* ... */
}
I'm using Dosctrine 2.1.
btw Doctrine 2.2 validates mappings as good, but I get same error at run time as with 2.1.
I think the problem is that EmailVerfication points to OurUSers intead of to Auth, the error message is misleading though. I am not sure the triple mapping is possible from the internals (i am pretty sure i implemented an exception for this some where as well, i have to look why this is not triggered).
You tell in your JoinColumn statements that you work with a user_id column.
But your column definition for OurUser::id creates a id column by default.
You either have to modify the JoinColumn statement to use id:
/**
* #Entity
* #Table(name="email_verification")
*/
class EmailVerification {
/**
* #Id
* #OneToOne(targetEntity="OurUsers")
* #JoinColumn(nullable=false, name="user_id", referencedColumnName="id")
* #var OurUsers
*/
private $id;
/* ... */
}
OR
add a Column annotation on OurUser::id, like that:
/**
* #Entity
* #Table(name="our_users")
*/
class OurUsers {
/**
* #Id
* #OneToOne(targetEntity="Auth")
* #Column(type="integer", name="user_id")
* #JoinColumn(nullable=false, name="user_id", referencedColumnName="user_id")
* #var Auth
*/
private $id;
/* ... */
}
I think it would be better to switch to something like this, it's a lot more clear and should create less problems:
/**
* #Entity
* #Table(name="auth")
*/
class Auth {
/** #Id #Column(type="integer", name="user_id") #GeneratedValue #var int */
private $id;
/* ... */
}
/**
* #Entity
* #Table(name="our_users")
*/
class OurUsers {
/**
* #Id
* #GeneratedValue
*/
private $id;
/**
* #OneToOne(targetEntity="Auth")
* #var Auth
*/
private $auth;
/* ... */
}
/**
* #Entity
* #Table(name="email_verification")
*/
class EmailVerification {
/**
* #Id
* #GeneratedValue
*/
private $id;
/**
* #OneToOne(targetEntity="OurUsers")
* #var OurUsers
*/
private $ourUser;
/* ... */
}

Categories