Search code examples
spring-dataspring-data-jpajpql

spring data load children and query by child property


I am using spring-data-jpa/hibernate/mysql

class A{
   private long id;
   private Collection<B> myBs;
}

class B{
   private long id;
   private int property;
}

I want to load an A with myBs collection loaded with all Bs where B.property > 5

so I did this:

private interface ARepository extends JpaRepository<A, Long>{

 @Query("SELECT a, b "
        + "FROM A a JOIN a.myBs b ON b.property > :prop"
        + "WHERE a.id= :id ")
 public A getByIdPastB(@Param("id") long id, @Param("prop") Integer prop);
}

however I get exception that too many As are retrieved from data store. Basically, it retrieved table

_______________________________
A.id  | B.id  | B.a_id| B.prop
2     | 1     | 2     | 8
2     | 2     | 2     | 11
2     | 3     | 2     | 7

and instead of building one A object and populating with 3 B objects, it is trying to build 3 A objects with one B object each.

Now I know fetch graphs manage to tell JPA to be smart about it, however here it did not work. How can I set it up to do it properly? Is there a way to do naming like

private A findWhereMyBsPropGreaterThan(Integer prop) and then just put an @EntityGraph annotation on it?


Solution

  • Ok, here it is:

    @NamedEntityGraph(name="full", attributeNodes={@NamedAttributeNode("myBs")})
    class A{
    }
    
    @EntityGraph("full)
    @Query("SELECT a"
            + "FROM A a JOIN a.myBs b ON b.property > :prop"
            + "WHERE a.id= :id ")
    public A getByIdPastB(@Param("id") long id, @Param("prop") Integer prop);