Multiple entities persist doctrine2 Zend - php

I have 3 Entities Users, UserProfile and Staffs
The User profile is linked to Users table through user id
The Staff table is linked to userprofile using the userprofileid
Admin create the user profile and generate the registration no, username and password.
I want add a user record to the users table then add the user profile and then add the profile id to the staff table.
I want to persist three entities sequentialy
I tried to create an instance for the Users like
$this->userent->setUsername('xxx');
$this->em->persist($this->userent);
$this->em->flush();
then:
$this->profileent->setFirstname('xxx');
$this->em->persist($this->profileent);
$this->em->flush();
Basically a form is shared among three entities and I want to insert into three tables sequentially,
Updated
Apart from users entity i have a usertype entity linked to users...i want to persist only the foreign key. i have
setUserType(Usertype $userType) method an instance of the user_type entity in users
when i do
$this->userent = new Users();
$this->userent->setUserType($this->em->getRepository('\Campus\Entity\Usertype')->findByUserType("admin"))
i get the error
Argument 1 passed to Campus\Entity\Users::setUserType() must be an instance of Campus\Entity\Usertype, array given
if i pass the value of the array which is an instance of Usertype
i get an error saying need an array for the ArrayCollection..help please!!!
Argument 1 passed to Doctrine\Common\Collections\ArrayCollection::__construct() must be of the type array, object given, called in D:\xampp\htdocs\zend\library\Doctrine\ORM\UnitOfWork.php on line 406 defined in D:\xampp\htdocs\zend\library\Doctrine\Common\Collections\ArrayCollection.php on line 46

Think less about the database, and more about your objects. That's the whole point of doctrine.
You want something like this:
<?php
// create some entities
$user = new Entity\User();
$user->setUsername('userman');
$profile = new Entity\UserProfile();
$profile->setFirstname('joe');
$profile->setLastname('smith');
$staff = new Entity\Staff();
$staff->setSomething('value-for-something');
// associate those entities together
$profile->setStaff($staff);
$user->setProfile($profile);
// assuming you have set up cascade={"persist"} on your associations
$this->em->persist($user);
// if you haven't set up cascade={"persist"}, you will need to call persist on each entity:
// $this->em->persist($profile);
// $this->em->persist($staff);
$em->flush();
So, the basic idea is you build up your objects, get them into Doctrine's Unit-of-Work (by calling persist() and maybe having some cascades set up), then write them all to the database in a single transaction by calling flush()

You can persist each entity, and then flush() one time at the end.
If you have relations between your entities, you can check the following annotation
cascade={"persist"}
"Cascades persist operations to the associated entities."
Have a look at the documentation here : http://docs.doctrine-project.org/en/2.0.x/reference/working-with-associations.html#transitive-persistence-cascade-operations

Related

Check if the user is attached or not yet

I'm working with Laravel on little project, i have a pivot table and I would like to attach new users, but I must check if the user is not already attached. how can I do ?
$user = User::findOrFail(2);
$user->liked()->attach(6);
dd($user);
How can I check if the user number 6 is already attached or not, so i can add the new record.
You may also use the sync method to construct many-to-many associations. The sync method accepts an array of IDs to place on the intermediate table. Any IDs that are not in the given array will be removed from the intermediate table. So, after this operation is complete, only the IDs in the given array will exist in the intermediate table:
$user = User::findOrFail(2);
$user->liked()->sync([6,//ids you want attach]);
dd($user);
If you do not want to detach existing IDs that are missing from the given array, you may use the syncWithoutDetaching method:
$user->liked()->syncWithoutDetaching([1, 2, 3]);
Also Refer This

Doctrine2 / Add Entity property but do not wan to create a column

With Doctrine 2, is it possible to add a new property to an entity to persist it in the entity manager, but NOT create a new column in the database ?
Purpose of that is to add a explain field to an entity and catch it with an event when UnitOfWork detects an update of one entity's value. (and perhaps send the content of the explain field by email, or log it, ...)
But I don't want to store this value in the database.

working with associations doctrine

How can i get information form associating doctrine. Here is an example ----
"EntityUser" is JOIN to "EntityApartment".
Many "User" can stay in the same "Apartment".
Now all user have unique id.
All "Apartment" values is been set dynamically, so ApartmentId can be set with many user.
So now if i want to get the Apartment name from "EntityApartment" how can i get that information, because in the "EntityApartment"** there is id, name, value and etc. So how can i get the associations value.
If I understand you correctly, I think you want to create a ManyToOne relashionship between your two entities. Once it is created, you do not have to think about foreign keys, as they are managed by Doctrine. You can simply use your property like you would do with any other. For example :
$user = new User();
$apartment = new Apartement();
$apartment->setAddress('12 xxx street');
$user->setApartement($apartment);
And you can access your user's appartment like this :
// Displays '12 xxx street'
$user->getApartment()->getAddress();
Hope this helps.

Doctrine many to one relationship persist operation

I have a story table and user table. The column userid in story table is a foreign key which refers the id in user table.
I have set the relationship is that a user may have many stories which is stored in story table. I have created the entities of both table.
But if try to persist operation only to story table it is asking the details for new user entry.
My objective is to add a new story with existing userId.
Am posting the error here:
A new entity was found through the relationship 'Story#_userId' that
was not configured to cascade persist operations for entity:
User#0000000038960c50000000008ea93852. To solve this issue: Either
explicitly call EntityManager#persist() on this unknown entity or
configure cascade persist this association in the mapping for example
#ManyToOne(..,cascade={\"persist\"}).
I set ManyToOne relationship in Story entity:
/**
* #ManyToOne(targetEntity="User", inversedBy = "_story" )
* #JoinColumns({
* #JoinColumn(name="user_id", referencedColumnName="id")
* })
*/
private $_userId;
I checked the database schema and it shows relationship is set correctly. So I have done the story insertion process.
$user = new User();
$user->setUserId($id);
$story = new Story();
$story->setContent("....");
$story->setUserid($user);
$this->em->persist($story);
$this->em->flush();
You are probably persisting the story entity but not the user. If you have something like this:
$story = new Story();
$user = new User();
$story->setUser($user);
$em->persist($story);
$em->flush();
This will result in a fatal error, since you are persisting one entity, but through its relations, Doctrine finds another new entity. You have two options:
Call persist on both entities:
$story = new Story();
$user = new User();
$story->setUser($user);
$em->persist($story);
$em->persist($user);
$em->flush();
Or, set up cascading persist for the Story entity. Eg. if you are using annotation mapping, you would do something like
/**
* #ManyToOne(targetEntity="User", inversedBy="stories", cascade={"persist"})
*/
private $author;
The chapter 8. Working with associations details this.
K. Norbert's answer hits the spot, but there is something that might be unclear. At least it was unclear for me, who came to doctrine from SQL.
The thing is doctrine seem to remember which objects are already persisted. Whenever it finds new (not persisted yet) objects related to entity you want to persist - it yells with 'A new entity was found through the relationship ...' error. When you want to save new object (only one entity, without persisting related entities) you just need to make sure related entities are persisted already.
So:
$story = new Story();
$entityManager->find('User', $id);
$story->setUser($user);
$em->persist($story);
$em->flush();
does the trick. Because doctrine knows the user is persisted already and it doesn't need to do it anymore. Doctrine knows because we got the user from the database.
Dont you think you should set User rather than Userid for story
$user = new User();
$user->setUserId($id);
$story = new Story();
$story->setContent("....");
$story->setUser($user); //change here
$this->em->persist($story);
$this->em->flush();
I'm struggling to understand what you need, so I'm not sure if this will respond to your question.
As the story.user_id id a foreign key of user.id (which is a primary key), this can't be empty/null. So if, let's say, you have a php session, you should probably store your user id (or user name) in your session variables, and when you create a new record in the story table, use the user id from your session to populate the story.user_id attribute.
Hope it helps.
I would be helpful if you attach your entites.
But I suppose that it is simmilar problem to mine. You cannot define the #Id and #ManyToOne together in one field. You have to use separate fields for an #Id and for relation #ManyToOne.
If you have a new (not persisted yet) User entity, you have to persist User which have cascade={"persist"} or cascade={"all"} in field correspond to Story entity. You can store the Story entity only if User already exists and it is attached to Doctrine.
Hope it help.

Doctrine2 - using a foreign key column as a normal field

Is there a way to have something like this in doctrine:
class Entity {
/**
* #Column(name="related_entity_id")
*/
private $relatedEntityId;
/**
* #ManyToOne(targetEntity="RelatedEntitiy")
* #JoinColumn(name="related_entity_id", referencedColumnName="id")
*/
private $relatedEntity;
}
What I want to do I do something like this:
call Entity::setRelatedEntityId($someId), and persist the entity,
and have the entity return the related entity by calling Entity::getRelatedEntity().
The related entity is selected from a table which will be strictly limited and it will never dynamically grow at runtime, so there is a finite number of related entity ids.
At the time of creating a new Entity, I'd like to set the related entity id, but without having to fetch the whole related entity from the database.
As far as I could test this, it does not work, because if I set the relatedEntityId but not the relatedEntity, Doctrine automatically sets the related_entity_id column to null, since basically no relationship has been established.
I've tried to do something like this also:
remove the relatedEntityId property, and use
Entity::setRelatedEntity(new RelatedEntity($relEntId))
the constructor of the RelatedEntity will set the id, but not other values.
I do not want to persist the RelatedEntity (it's values are already set in the DB for the given $relEntId), but this time Doctrine signals an error at flush, because it has an unpersisted entity.
Basically, what I want to do is create a relationship without knowing anyhing but the Id of the related entity. If there is some other way this can be done, please share.
Thanks in advance
EDIT:
I've found a workaround. Since the RelatedEntities will be a limited set of immutable objects, I've done the following:
use the entityManager to find all RelatedEntities;
inject the list to the object that will be creating new Entities
when creating a new Entity, select one of the RelatedEntities from the list as its RelatedEntity
I'll leave the question open for a day or two, just in case somebody comes up with something better.
Use the entity proxy:
Entity::setRelatedEntity($entityManager->getReference('RelatedEntity', $relEntId))
I don't think this is supposed to work like how you described :)
The entity you add must be a Doctrine managed object, so that means you have to load it yourself first using the find() family of methods.
Based on my experience with Doctrine 2 further elaborated here http://ssmusoke.wordpress.com/2012/03/25/doctrine2-day-3-proxies-associations-relationships/
My approach is as follows:
a) Have only the $relatedEntity property
b) Add a getRelatedEntityId() function which returns the id value from $relatedEntity
c) Add a setRelatedEntityId() which sets the $relatedEntity object - you may need to load it from the database, saves you from polluting other layers when u only have the id of the related entity
d) Add getRelatedEntity() and setRelatedEntity() functions
BOTTOM LINE: You cannot have a property for the foreign key column and the mapped property as Doctrine gets confused

Categories