doctrine 2 duplicate entity when add with foreign key - php

I have 2 tables in db : 'User' & 'Task'.
The task has a foreign key IdUser in cascade and this is the doctrine annotation on it :
/**
* #var \MyBundle\Entity\User
*
* #ORM\ManyToOne(targetEntity="\MyBundle\Entity\User", cascade={"persist"})
* #ORM\JoinColumns({
* #ORM\JoinColumn(name="idUser", referencedColumnName="id")
* })
*/
private $idUser;
My problem is when i try to create a new Task :
I set my task with my current user and then i persist & flush it. Everything goes fine exept that in database instead of linking this task to my current user, it duplicates my current user and link my Task to the new duplicated user.
Any idea how to avoid this ?

Related

Symfony 4 : Doctrine migrate with manyToOne join

I trying Symfony 4 for "fun". And for that I try to rewrite an old website without framework as the moment, with Symfony 4.
For that I configure my app on my database with existing datas. And I'd make login form.
BUT on my User classe, I have some colomn who make me some issues.
See bellow my user's class's annotations:
/**
* Utilisateur
*
* #ORM\Table(name="utilisateur", uniqueConstraints={#ORM\UniqueConstraint(name="mail", columns={"mail"})}, indexes={#ORM\Index(name="FK_UTILISATEUR_idDroit", columns={"idDroit"})})
* #ORM\Entity
*/
and my user's struct :
idutilisateur
nom
prenom
mail
password
dateinscription
datevalidation
token
iddroit
plainPassword
Like you can see, I create before iddroit as foreign key of droit's table.
Doctrine generated the propertie as
/**
* #var Droit
*
* #ORM\ManyToOne(targetEntity="Droit")
* #ORM\JoinColumns({
* #ORM\JoinColumn(name="idDroit", referencedColumnName="idDroit")
* })
*/
private $iddroit;
And created the getter as
public function getIddroit(): Droit
{
return $this->iddroit;
}
And after followed the documentation about registration / login, the debugger respond =>
Return value of App\Entity\Utilisateur::getIddroit() must be an
instance of App\Entity\Droit, null returned
So I imagine he want an object and not just an ID, even if in anotation it's making the Join rules. Any ID what's happened ?
And I understand to return an objet, but I have no idea how to return that.
If any suggestion.
Thanks guys ;)
Laurent

Cannot delete a records (OneToMany) with Symfony

I have 2 entities linked together PICTURE <-(OneToMany)-> NOTE (see class details below). When I tried to delete a picture record I got the following message from Symfony
An exception occurred while executing 'DELETE FROM Picture WHERE id =
?' with params [118]: SQLSTATE[23000]: Integrity constraint violation:
1451 Cannot delete or update a parent row: a foreign key constraint
fails (symfony.note, CONSTRAINT FK_6F8F552A8671F084 FOREIGN KEY
(picture_id) REFERENCES Picture (id))
I find it strange because if the note.author_id is the same as the current user, then I can delete the picture (and the note associated to the picture) without any problem.
here some details of my class picture and note:
Class Picture
{
/**
* #ORM\OneToMany(targetEntity="XXX\XXXBundle\Entity\Note", mappedBy="picture", cascade={"persist", "remove"})
* #ORM\JoinColumn(name="note_id", referencedColumnName="picture_id", onDelete="CASCADE")
**/
private $notes;
}
Class Note
{
/**
* #ORM\Id
* #ORM\ManyToOne(targetEntity="XXX\XXXBundle\Entity\Picture", inversedBy="notes")
**/
private $picture;
/**
* #ORM\Id
* #ORM\ManyToOne(targetEntity="Sdz\UserBundle\Entity\User", cascade={"persist"})
*/
private $user;
}
Here my controller to delete the picture. FYI picture is a collection in my form. I set the option allow_delete to true
foreach($pictures as $picture) // $pictures is the initial list of picture
{
if(false === $data_form->getPictures()->contains($picture))
{
$em->remove($picture);
}
}
You have constraints on database that prevents you from cascaded deleting. I would suggest to use phpMyAdmin tool (mysql command line would be horrible to use for checking constraints): open both tables structure tab, go into relational view, and here check how constraints are set.
You may have different constraints set inside doctrine mappings and inside database, and it may work fine, until you try to perform an action on database, that collides with database constraints, like here.

ManyToOne relationship + How to use in both directions

I have 2 tables like this:
Users
- UserID
- Username
- Password
- ...
Players
- playerID
- playerName
- ...
- User
The relation is ManyToOne (see the picture) and it's not required.
I've generated my entities automatically with Doctrine. In my player Entity I have:
/**
* #var \NV\VolleyScoutBundle\Entity\Users
*
* #ORM\ManyToOne(targetEntity="NV\VolleyScoutBundle\Entity\Users")
* #ORM\JoinColumns({
* #ORM\JoinColumn(name="user_id", referencedColumnName="user_id")
* })
*/
protected $user;
But I don't have a $player variable in my Users Entity. In what way can I add this? Tried to do this but gave me different errors. What I'm trying to do is add a player form to my register form.
So in my RegisterType (=form) I woud like to add ->add('player', new PlayerType()). But that's not possible without a $player variable in my Users entity.
What type of relation do I need to setting for $player in my Users entity?
You have to add annotation in user entity.
In Player Enity
#ORM\OneToMany(targetEntity="Players", mappedBy="user")
protected $player;
In User Entity:
#ORM\ManyToOne(targetEntity="Users", inversedBy="player")
#ORM\JoinColumn(name="user_id", referendecColumn="UserId")
proteced $user;
This is only a draft. You have to write full namespaces for target entities, and correct errors if there are some.
A lot of setails you can find here: Doctrine documentation - working with association
Try to use small caps for table names, because MySQL under linux doesn't like uppercaps.
$player must be instance of ArrayCollection

Symfony2 and Doctrine2 - Set onDelete

I have two entities:
Manuscript and Tasks.
In the tasks table, I have the manuscript id and some extra data.
Also, in the tasks entity I have
/**
* #ORM\OneToOne(targetEntity="Manuscript")
* #ORM\JoinColumn(name="manuscript_id", referencedColumnName="id", onDelete="CASCADE")
**/
private $manuscript;
But I would like to delete the specific task when deleting the menuscript.
When trying to delete the manuscript, I am getting:
SQLSTATE[23000]: Integrity constraint violation: 1451 Cannot delete or update a parent row: a foreign key constraint fails
IS it possible to do this with the onDelete, or should I delete the task manually?
Thank you.
Done by adding:
/**
* #ORM\OneToOne(targetEntity="Task", mappedBy="manuscript", cascade={"remove"})
*/
private $task;
In the manuscript entity.

Symfony2 entity field in a form

I'm trying to create a simple form to add companies and i've a trouble using an entity.
I added a select field using a company type entity :
->add('idtypesociete', 'entity', array('class' => 'PromocastUtilisateurBundle:PcastTypesociete', 'property' => 'nomtypesociete'))
But when i submit the form my idtypesociete field contain an 'PcastTypesociete' object and not just the value of the option selected. So the submission fail.
I made a Many-To-One relation between my company entity and my typeCompany entity like this:
/**
* #var integer $idtypesociete
*
* #ORM\Column(name="IDTYPESOCIETE", type="integer", nullable=false)
* #ORM\ManyToOne(targetEntity="Promocast\UtilisateurBundle\Entity\PcastTypesociete")
* #ORM\JoinColumns({
* #ORM\JoinColumn(name="PcastTypesociete_idtypesociete", referencedColumnName="idtypesociete")
* })
*/
private $idtypesociete;
Do you have a solution to get only the id of the company type selected? (if possible without made a simple sql request to list my companies types)
Thanks a lot !
If the relationships are working then Symfony 2 usually does a very good job of building the form fields for you.
I think the issue is the $idtypesociete property. Are you expecting to store an integer here on the hydrated entity?
Doctrine associations use Entity relationships. The annotations you supply determine the behind-the-scenes stuff like the join column:
http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/reference/association-mapping.html#many-to-one-unidirectional
I suggest backing up or committing your work before doing anything else.
Does changing the entity property to the following help?
/**
* #var PcastTypesociete $typesociete
*
* #ORM\Column(name="IDTYPESOCIETE", type="integer", nullable=false)
* #ORM\ManyToOne(targetEntity="Promocast\UtilisateurBundle\Entity\PcastTypesociete")
* #ORM\JoinColumns({
* #ORM\JoinColumn(name="PcastTypesociete_idtypesociete", referencedColumnName="idtypesociete")
* })
*/
private $typesociete;
You may need to update your database schema via doctrine:schema:update using the console if it doesn't work properly the first time. Your Entity will also need to be updated to reflect the new property name.
If that works then your form should only need ->add('typesociete') in the form type and you'll have a functioning entity select field because Symfony is clever enough to know what field type to use.

Categories