Can I order the joined entities in Doctrine2? - doctrine-orm

Say I've got two entities: Entity1 and Entity2. Entity1 has many Entity2's.
Can I make a query in doctrine2 to select all the Entity1 with their inner Entity2s ordered by some field?
//I'd need this query but with the Entity2s ordered within each Entity1
SELECT e1,e2 FROM 'BundleName:Entity1' e1 JOIN e.entity2s e2;
I'd need to do this without the #OrderBy("somefield") annotation in Entity2.

You'll need to add a ORDER BY clause to the DQL same as you would do with native SQL. When you want to order multiple fields you can simply seperate them with a comma. In your case you want to order entity1 first by their unique identifier, next you sort by a field of entity 2.
Your final query would look something like this:
SELECT e1,e2 FROM 'BundleName:Entity1' e1 JOIN e.entity2s e2 ORDER BY e1.id, e2.somefield;

Related

Django Filter on Distinct with orderby created at

How can I filter with distinct and order by
IncomingCallRecording.objects.filter().order_by("lead_id","-created_at").distinct("lead_id")
Problem:
Order by is not working with created at
Is there an alternative solution that might help
You can just use created_at in order_by.
IncomingCallRecording.objects.order_by("-created_at").distinct("lead_id")
Multiple columns sorting is done in sequence. If you define two columns in order_by, it sorts by first column and then second column (first by lead_id, and then within each lead_id sort by created_at).
Update
The solution would be subjected to database. For MYSQL, DISTINCT ON isn't allowed. For POSTGRES, DISTINCT ON expression must match ORDER BY.
In case of POSTGRES, you will need to use Subquery, if you would like to use different DISTINCT ON and ORDER BY expressions.
IncomingCallRecording.objects.filter(
pk__in=Subquery(
IncomingCallRecording.objects.distinct('lead_id').values('pk')
)
).order_by('-created_at')

How to reference elements from a joined table in a DQL statement

I have two entities (AdminMembers\Entity\Members and AdminEvents\Entity\Invitees) that are joined with a OneToMany relationship. Because the relationship is defined in the entities, I can use the following DQL statement to query the data:
$dql = "SELECT i FROM AdminEvents\Entity\Invitees i WHERE i.eventID=$eventID";
And, through this configuration I can use statements like $invitee->getMember()->getMemberLastName() in my ZF2 view script to get the data from the joined entities.
Now, if I want to sort the data in the DQL statement by fields in AdminMembers\Entity\Members, I run into a problem. The following statement
$dql = "SELECT i FROM AdminEvents\Entity\Invitees i WHERE i.eventID=$eventID ORDER BY i.memberLastName, i.memberFirstName";
throws the error message
Class AdminEvents\Entity\Invitees has no field or association named memberLastName
This is because the fields memberLastName and memberFirstName are defined in AdminMembers\Entity\Members. Although an association does exist, I'm certain I’m just missing some syntax in referencing memberLastName and memberFirstName.
I know that I can expand the DQL statement to join the entities in the DQL statement, which would allow me to identify the joined table and relate the elements to table identifier. But, since the tables are already joined in the entity definitions, they shouldn’t have to be joined again.
Is there a special syntax for referencing joined-table entities in the DQL statement without "rejoining" the tables in the statement?
You should join the members entity to be able to sort by its fields. See docs:
$dql = "SELECT i, m FROM AdminEvents\Entity\Invitees i JOIN i.member m WHERE i.eventID=$eventID ORDER BY m. memberLastName, m.memberFirstName";

Select no fields from table in Korma

I'm trying to do a join across a number of tables (three plus a join table in the middle). I think korma is lazily evaluating the last join. What I'm trying to do is to add a condition that restricts the results of the first table in the join, but I'm only interested in fields from the last table in the join.
So for example say I've got clubs, people and hobbies tables, and a people-to-hobbies join table for the last two. Each club can have many people, and each person can have many hobbies.
I'm trying to get the full details of all the hobbies of people who belong to a specific club, but I don't want any fields from the club table. The join table means that korma will create two queries, one to get all the people that are in a specific club, and another to retrieve the hobbies for that person via the people-to-hobbies join table.
My korma query looks something like this:
(select clubs
(with people
(with hobbies
(fields :hobby-name :id)
(where {:clubs.name "korma coders"}))))
The problem is that I haven't specified which fields I want from clubs and people, and the default is to select *. How can I include no fields from these tables? Is this possible, or does the fact that the hobbies are lazily loaded mean korma has to return some results in the first query (which gets me a filtered list of people), so that when I come to interrogate it later for the hobbies, it has the ids it needs to run the second query?
I'd use join macro in such case:
(select clubs
(join people)
(join people-to-hobbies)
(join hobbies)
(fields :hobbies.hobby-name :hobbies.id)
(where {:clubs.name "korma coders"}))))
It's a bit more explicit, but as an additional benefit it's run with a single query.

Open JPA how do I get back results from foreign key relations

Good morning. I have been looking all over trying to answer this question.
If you have a table that has foreign keys to another table, and you want results from both tables, using basic sql you would do an inner join on the foreign key and you would get all the resulting information that you requested. When you generate your JPA entities on your foreign keys you get a #oneToone annotation, #oneToMany, #ManyToMany, #ManyToOne, etc over your foreign key columns. I have #oneToMany over the foreign keys and a corresponding #ManyToOne over the primary key in the related table column I also have a #joinedON annotation over the correct column... I also have a basic named query that will select everything from the first table. Will I need to do a join to get the information from both tables like I would need to do in basic sql? Or will the fact that I have those annotations pull those records back for me? To be clear if I have table A which is related to Table B based on a foreign key relationship and I want the records from both tables I would join table A to B based on the foreign key or
Select * From A inner Join B on A.column2 = B.column1
Or other some-such non-sense (Pardon my sql if it is not exactly correct, but you get the idea)...
That query would have selected all column froms A and B where those two selected column...
Here is my named query that I am using....
#NamedQuery(name="getQuickLaunch", query = "SELECT q FROM QuickLaunch q")
This is how I am calling that in my stateless session bean...
try
{
System.out.println("testing 1..2..3");
listQL = emf.createNamedQuery("getQuickLaunch").getResultList();
System.out.println("What is the size of this list: number "+listQL.size());
qLaunchArr = listQL.toArray(new QuickLaunch[listQL.size()]);
}
Now that call returns all the columns of table A, but it lack's the column's of table B. My first instinct would be to change the query to join the two tables... But that kind of makes me think what is the point of using JPA then if I am just writing the same queries that I would be writing anyway, just in a different place. Plus, I don't want to overlook something simple. So what say you stack overflow enthusiasts? How does one get back all the data of joined query using JPA?
Suppose you have a Person entity with a OneToMany association to the Contact entity.
When you get a Person from the entityManager, calling any method on its collection of contacts will lazily load the list of contacts of that person:
person.getContacts().size();
// triggers a query select * from contact c where c.personId = ?
If you want to use a single query to load a person and all its contacts, you need a fetch in the SQL query:
select p from Person p
left join fetch p.contacts
where ...
You can also mark the association itself as eager-loaded, using #OneToMany(lazy = false), but then every time a person is loaded (vie em.find() or any query), its contacts will also be loaded.

DQL join between unrelated entities?

Can I have a DQL join between unrelated entities using WITH DQL operator? OR is definign relationship absolutely mandatory?
I have a unidirectional relationship with Category and CategorySubsription. Where CategorySubscription has a many to one unidirectional relationship with Category. I want to grab a list of Categories c and left join CategorySubscription cs WITH cs.category_id = c.id AND cs.user_id = value.
Can I do this somehow?
Starting with Doctrine version 2.3 you can, as mentioned in a blog.
It's also mentioned in the docs if you know where to look. Scroll down to the last example under "15.2.4. DQL SELECT Examples":
Joins between entities without associations were not possible until version 2.4, where you can generate an arbitrary join with the following syntax:
<?php
$query = $em->createQuery('SELECT u FROM User u JOIN Blacklist b WITH u.email = b.email');
I know it says "not possible until version 2.4", but it definitely works starting with 2.3!
You can try using multiple from() methods and join conditions put in where() or andWhere methods()