Am I missing a point with Doctrine? It's been very useful for some scenarios, but for the basic scenario of retrieving an entity using an Id (say using find() or findOneBy()) why do you see a query being fired off for every relationship to populate the main entity's properties?
Surely with the mapping/annotations I've created, Doctrine should be capable of a few joins and one query, without having to write a DQL query for the retrieval of each entity.
Or, as I'm predicting, have I missed the point somewhere!
Just add the aliases of related entities to select part of your query.
Let’s say, you have Book related one-to-many to Cover, and you want so select some books with their covers.
With query builder, use:
->createQueryBuilder()
->select("book, cover")
->from("Book", "book")
->leftJoin("book.covers", "cover")
With query, use:
SELECT book, cover FROM Book book LEFT JOIN book.covers cover
As the result, you will receive collections of Book with prepopulated $covers collection.
Because the relationships are hydrated only when needed - by default Doctrine uses a lazy-loading strategy.
If you already know that you will access the related entities, you should build a DQL query that retrieves the record AND the related entities.
Related
I have several entities with several relations. They have one "starting" entity. When I want to persist data to my database, I set the data to each entity (implicitly with a method I wrote, because I import that data from an xml), but only persist and flush the main entity. I used cascade:persist in the entities accordingly. And all that works just fine.
But: There are entities (the OneToMany side) that should check in the database, whether or not the record already exists and only set a new record, if not. And if the record exists the ManyToOne side should get that foreign key, that already exists.
Is there an easy way to tell doctrine to do so on my single persist/flush of the main entity?
edit
Maybe I can simplify the question to:
Is it possible to flush an object and doctrine will check if this record already exists in the database (in one query)? Or do I have to do make a query to check for existing records first and then a second query with my data to be set?
edit end
Thanks a lot for your help
David
I have different entities like:
Element, Status, Action, Contributor ...
And I need to create an entity, let say Synonym, which can be related to one of these previous entities
My entity Synonym, can be a synonym of the entity Element or Status or Action ...
I try to use a MappedSuperclass but I'm really lost.
I think this kind of relation is common and must be easy to create with doctrine but I can't find the good way.
I have 2 entities, User and Profile. Profile has in-symfony relation with User, but there is no in-database relation (no foreign key, no cascade) - only simple int column named user_id and nothing more.
Problem is obvious: when i delete user - associated profiles persists, but their user_id points to non-existing user row.
Since I use in-symfony relations when i fetch profile from database it fetches also related user entity. I expected that if there is no row with specific ID, it would just leave null or at least throw an exception or something.
Problem is that symfony creates empty User entity object with only id set. rest of its fields are null.
I know solution would be to create FK, constraints etc ... but I'm not allowed to touch anything in database schema.
How can I manage this problem ? I could even leave those empty object if only i had simple way to determine if they exist in database inside TWIG - so i would know if i can display {{ profile.user.email }} for example.
Fast and dirty solution, as you ask, is to use this test: http://twig.sensiolabs.org/doc/tests/defined.html
But I strongly recommend to rework your entity relations.
Found solution: its fetch: EAGER set to problematic mapping in doctrine.
By default doctrine uses LAZY fetching what results in using Proxy classes generated by doctrine for related entity. That class is almost same as real entity class. Difference is inside getter methods that before returning value performs fetching entity from database.
At this point, when you call getter on such proxy, doctrine tries to find entity in database using its ID, and since it doesn't find anything it throws exception.
When using EAGER fetching doctrine performs fetching of related entities on the same time when it fetches main entity and if it doesn't find it then sets null on relation field.
I am new programmer student, now i develop mobile app with phonegap. So I use sqlite and persistence js.but I don't know how to write "inner join" in persistence js function. Hope all of you help me.
Take a look at documentation:
https://github.com/zefhemel/persistencejs
Some text from it:
The methods to define relationships to other entities:
EntityName.hasMany(property, Entity, inverseProperty)
defines a 1:N or N:M relationship (depending on the inverse property).
EntityName.hasOne(property, Entity)
defines a 1:1 or N:1 relationship.
If an object has a hasOne relationship to another which has not yet been fetched from the database (e.g. when prefetch wasn't used), you can fetch in manually using fetch. When the property object is retrieved the callback function is invoked with the result, the result is also cached in the entity object itself.
obj.fetch(prop, callback)
I have created my Database which has:
Artist, tracks and TracksPerArtists
I can do sql queries through the entity model. For example when I make:
database.TRACK.ToList()
I get the list of track to be shown on index view for example. But my foreign keys come empty. While there is an artist and a track, and the correct row for ArtistsPerTrack, this item in my track.ToList() collection is empty.
Is there a different way to fetch those data?
I came from cakePHP framework in which you can define the Model.recursive property to declare the depth of the relations you want to fetch.
Is there anything similar here?
There is something similar.
If "database" is DataContext and Artist and Tracks have many to many relationship in database, you can fetch related entities using Include clause:
database.TRACK.Include("Artists").ToList()
where "Artists" is the name of property on Track entity.