Symfony 2 Querying Doctrine-mapped objects - symfony

I am experiencing an issue when querying for information across objects in my controller. Please let me know if I need to expand on the information provided (I changed the names of the objects to be more clear outside of context).
I have a oneToOne Bidirectional Mapping across two entities that are in separate bundles.
Object 1:
oneToOne:
person:
targetEntity: Program\PersonBundle\Entity\Person
fetch: EAGER
inversedBy: group
joinColumn:
name: id
referencedColumnName: id
Object 2:
oneToOne:
group:
targetEntity: Program\GroupBundle\Entity\Group
mappedBy: person
fetch: EAGER
I have the appropriate variables in each of the Entity.php files for each object. My question is regarding accessing this information in my controller. When I try to access information across the bundles, it doesn't grab it on the first call. However, when I call it again, it grabs the information properly. Does anyone know why this is? Isn't 'fetch: EAGER' supposed to solve that issue?
$em = $this->getDoctrine()->getEntityManager();
$personsRepository = $em->getRepository("PersonBundle:Person");
foreach($persons as $person)
{
$person->getGroup()->getName(); // This doesn't return anything
$person->getGroup()->getName(); // This returns the group name....
}
Thanks in advance!

Related

Symfony2 FosUserBundle is not hydrating User Entity with custom Entity

I have my own User Entity which extends the Fos one. It is capable of having another Entity attached to it as a manyToOne relationship.
Using the following code inside my own Profile Controller results in this Entity not being added to the User Entity.
$user = $repo->find($user->getId());
All my other custom fields are in place, its just this Entity that is missing. The relationship looks like this
manyToOne:
game_system:
targetEntity: Acme\NameofBundle\Entity\GameSystem
joinColumn:
onDelete: SET NULL
name: game_system_id
referencedColumnName: id
Edit
It's worth noting that the getGameSystem call works inside my main Bundle, NameofBundle.
But it fails inside of MemberBundle, MemberBundle extends FOSUserBundle. The GameSystem Entity is inside NameofBundle while my User is my MemberBundle.
Edit 2
My config.yml
fos_user:
db_driver: orm
firewall_name: main
user_class: Acme\MemberBundle\Entity\User
group:
group_class: Acme\MemberBundle\Entity\User
There seems to be a problem with the line:
$user = $repo->find($user->getId());
which seems redundant
How can you id from user if you haven't fetched user from database yet?
or, if you have already user object you don't need to get it from database.
The following would be more correct and to get the id you want you'd have to make a list with findAll().
$user = $repo->find($id);

destroy a one-to-one relationship in doctrine

I have a relationship like the one in doctrine's docs so i'll use it as an example:
Product:
type: entity
oneToOne:
shipping:
targetEntity: Shipping
joinColumn:
name: shipping_id
referencedColumnName: id
I'm attempting to delete a Shipping entity but am getting a foreign key constraint exception because the Product's row holds a reference to it. What's the proper way of handling this? Is there something in the yaml that i can add to take care of this? Or do i need to do something like below:
$product->setShipping(null);
$entityManager->persist($product);
$entityManager->remove($shipping);
$entityManager->flush();
You should set the onDelete option to CASCADE if you want the Shipping to be removed too, or to SET NULL if you want to delete just the Product.
Product:
type: entity
oneToOne:
shipping:
targetEntity: Shipping
joinColumn:
name: shipping_id
referencedColumnName: id
onDelete: "SET NULL"
You can read more about this on the Doctrine docs.

manyToOne is creating new products

I am trying to implement Sylius Cart Bundle, but every time I add a product to the cart, a new product is created.
This is probably link to my line:
cascade: ["persist", "remove"]
In my YAML File:
Pharmacie\FrontBundle\Entity\CartItem:
type: entity
table: app_cart_item
manyToOne:
produit:
targetEntity: Pharmacie\FrontBundle\Entity\Product
cascade: ["persist", "remove"]
joinColumn:
name: product_id
referencedColumnName: id
But if take it off, I get an error:
A new entity was found through the relationship 'Pharmacie\FrontBundle\Entity\CartItem#produit' that was not configured to cascade persist operations for entity: 3test2. 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"})
According to the doctrine doc, this error occurs when you set a new object.
But I am only getting an existing object By ID:
$product = $this->getProductRepository()->find($productId);
$item->setProduit($product); //this generates the error
$item->setUnitPrice(5); //this works fine
I don't understand why it's save as a new object.
If I use merge instead of persist, I get the same error:
A new entity was found through the relationship...
Found it (finally...) !
I had 2 entity manager mixed up. This iw why the doctrine wanted to store it as a new object all the time.
The mistake was in the services.yml file, on a listener.
Maybe it can help someone to look in the good direction.

Multiple One-To-One relationships in same entity with YAML in Symfony2

I am designing one entity that should have two One To One relationships to two different tables. My main entity (Player) has these definitions:
oneToOne:
attributesRegular:
targetEntity: AttributesRegular
oneToOne:
attributesNormalized:
targetEntity: AttributesNormalized
Now in the AttributesRegular I have this: (similar to AttributesNormalized)
oneToOne:
player:
targetEntity: Player
inversedBy: attributesRegular
joinColumn:
name: player_id
referenceColumnName: id
The problem is that when I generate the classes (and the DB schemas), only attributesNormalized is added, but not attributesRegular as well.
Can someone point to me what is wrong with my YML ?
Thanks!
You only need to state oneToOne once in Player otherwise you are rewriting the key/value rather than adding a value to it.
oneToOne:
attributesRegular:
targetEntity: AttributesRegular
attributesNormalized:
targetEntity: AttributesNormalized

Symfony2 - EntityNotFoundException

I have a Stats entity that is related to a Journey entity through a ManyToOne association.
id:
index:
type: integer
fields:
idJourney:
type: string
// data fields...
manyToOne:
journey:
targetEntity: Journey
joinColumn:
name: idJourney
referencedColumnName: idJourney
The Journey is related to the Station entity through two ManyToOne association: one for the first Station of the Journey, one for the last.
id:
idjourney:
type: string
fields:
idFirstStation:
type: string
idLastStation:
type: string
// other info fields
manyToOne:
firstStation:
targetEntity: Station
joinColumn:
name: idFirstStation
referencedColumnName: idStation
lastStation:
targetEntity: Station
joinColumn:
name: idLastStation
referencedColumnName: idStation
Finally, the Station entity :
id:
idStation:
type: string
fields:
name:
type: string
// other station info
I retrieve a collection of Stats objects with all related sub-objects via a custom Repository method which works fine.
$statCollection = $statsRepository->getStatsByDateAndArea($date, $area);
//This retrieves the expected data
$statCollection[0]->getJourney()->getFirstStation()->getName();
However, iterating through the collection with a foreach loop doesn't work:
foreach($statCollection as $stat) {
$journey = $stat->getJourney(); // works fine
$firstStationId = $journey->getFirstStationId(); // works too
$firstStation = $journey->getFirstStation(); // still works, but returns a Proxies\AcmeAppPathWhateverBundleEntityStationProxy object instead of a AcmeAppPathWhateverBundleEntityStation, but this should be transparent (as per Doctrine documentation)
$firstStationName = $firstStation->getName(); // throws an EntityNotFoundException
}
Any idea what's going on ? Should I force Doctrine to fetch all sub entities ?
EDIT
The error message is fairly laconic :
EntityNotFoundException: Entity was not found.
Not very helpful...
I ended up querying explicitly for the full set of sub-entities in my custom repository method...
I changed this query :
->select('stats')
->leftJoin('stats.journey', 'j')
->leftJoin('j.firstStation', 'fs')
->leftJoin('j.lastStation', 'ls')
to :
->select('stats, j, fs, ls')
->leftJoin('stats.journey', 'j')
->leftJoin('j.firstStation', 'fs')
->leftJoin('j.lastStation', 'ls')
I guess Doctrine's use of Proxy objects are not all that transparent...

Resources