问题
So I'm trying to write a JPA query based on the classes below (dumbed down a bit) that will produce the following:
So I have two objects: Thing and Person. A Person can hold a reference to a single Thing. Here are simplified version of the Classes:
public class Thing {
@Id
public Long id;
public String name;
public String description;
}
public class Person {
@Id
public Long id;
public String firstname;
public String lastname;
@ManyToOne
public Thing thing;
}
I'm trying to write a JPA query that will give me all the details of every Thing object as well as the number of times that Thing object is referenced by a Person object. Note that a Person could have the value null for Thing. Also a Thing object might not be referenced by any Person object at all but should still be listed.
So given the following tables:
Thing Table
| id | name | description |
| 1 | thg1 | a thing |
| 2 | thg2 | another one |
| 3 | thg3 | one more |
Person Table
| id | firstname | lastname | thing |
| 1 | John | Smith | 1 |
| 2 | Simon | Doe | 3 |
| 3 | Anne | Simmons | 1 |
| 4 | Jessie | Smith | 1 |
| 5 | Adam | Doe | 3 |
| 6 | Phil | Murray | null |
I would end up with a result like:
| id | name | description | amount |
| 1 | thg1 | a thing | 3 |
| 2 | thg2 | another one | 2 |
| 3 | thg3 | one more | 0 |
How would I go about writing that JPA Query? (If it makes a difference I'm using the Play Framework 1.2.5)
回答1:
It should be something like this:
select t.id, t.name, t.description, count(p) as amount
from Person as p right join p.thing as t group by t.id
The reason for the unusual "right join" is that JPA queries requires mappings between query classes and you only have one from Person
to Thing
.
If you had a mapping from Thing
to Person
:
class Thing {
...
@OneToMany
Set<Person> persons;
}
you could use the classic "left join":
select t.id, t.name, t.description, count(p) as amount
from Thing as t left join t.persons as p group by t.id
回答2:
Ok, If I am writing a pure JPQL and setting Entity relationship then I would go like this:
public class Thing {
@Id
public Long id;
public String name;
public String description;
@OneToMany
public Collection<Person> personList;
}
public class Person {
@Id
public Long id;
public String firstname;
public String lastname;
}
Query:
SELECT t from Thing {WHERE watever condition you may have}
Iteration:
Collection<Thing> thingList = query.getResultList();
System.out.println("| id | name | description | amount |");
for(Thing thing:thingList){
System.out.format("| %s | %s | %s | %s |%n", thing.getId(), thing.getName(), thing.getDescription(), thing.getPersonList().size());
}
来源:https://stackoverflow.com/questions/15768429/jpa-query-select-many-to-one-query-with-a-count