Issue
Suppose I have a Foo
entity (fields: id
, name
and barId
) and a Bar
entity (fields: id
, age
), in a one-to-many relation. I want to select all the Foo
s, having the corresponding Bar age
attached.
I see 2 options, but none seems to work:
- The so-called closed projection approach
@Query("select f as foo, b.age as age from Foo f inner join Bar b on f.barId = b.id")
List<FooWithAge> query1();
where FooWithAge is an interface having as methods Foo getFoo()
and Integer getAge()
;
- The so-called class projection approach
@Query("select new FooWithAge(new Foo(f), b.age) from Foo f inner join Bar b on f.barId = b.id")
List<FooWithAge> query2();
where FooWithAge is a class having as fields Foo foo
and Integer age
and a constructor that takes these 2 as parameters.
None of these solutions seem to work. A third solution, of taking all the fields of Foo as parameters of the constructor of FooWithAge works, but I would like to find a cleaner solution.
Note: I cannot use anything else than vanilla Spring Data JPA queries. Native queries are excluded.
Solution
- For foo object you have to define a sub-interface:
public interface FooWithAge {
String getAge();
FooView getFoo();
interface FooView {
//list of getters of foo
}
}
- In the first parameter you are creating a foo in a foo, so basically you have just to pass
f
:
@Query("select new FooWithAge(f, b.age) from Foo f inner join Bar b on f.barId = b.id")
List<FooWithAge> query2();
Answered By - frascu
Answer Checked By - David Goodson (JavaFixing Volunteer)