gallo8
gallo8

Reputation: 53

How to fetch Parent Entity with its Child Entities and their Child Entities with one query with join fetch

Entity Parent has multiple one to many associations as you can see below. Child entity has also one to many associations.

I successfully writed query which fetch Parent entity with child entities:

entityManager.createQuery("select p from Parent p " +
"left join fetch p.child1  " +
"left join fetch p.child2  " +
"where p.parentId = :parentId", Parent.class);

After this query executes, additional query are executed for every another level of child entities, so for every child of child.

Is it possible to fetch parent entity with all child entities and child of child entities in one query?

Object looks like:

public class Parent {

  @Id
  @GeneratedValue(strategy=GenerationType.IDENTITY)
  private Long parentId;

  \\other attributes

  @OneToMany(
   mappedBy = "parent",
   cascade = CascadeType.ALL,
   orphanRemoval = true
  )
  private Set<Child1> child1= new HashSet<>();

  @OneToMany(
    mappedBy = "parent",
    cascade = CascadeType.ALL,
    orphanRemoval = true
  )
  private Set<Child2> child2= new HashSet<>();

  ...
  // other associations are removed because they are the same
  //Constructors, getters and setters removed for brevity

}

public class Child1{

  @Id
  @GeneratedValue(strategy=GenerationType.IDENTITY)
  private Long child1Id;

  \\other attributes

  @ManyToOne(fetch = FetchType.LAZY)
  @JoinColumn(name = "parent_id")
  private Parent parent;

  @OneToMany(
    mappedBy = "child1",
    cascade = CascadeType.ALL,
    orphanRemoval = true
  )
  private Set<ChildOfChild1> childOfChild1= new HashSet<>();

  //Constructors, getters and setters removed for brevity

 }

public class Child2{

  @Id
  @GeneratedValue(strategy=GenerationType.IDENTITY)
  private Long child2Id;

  \\other attributes

  @ManyToOne(fetch = FetchType.LAZY)
  @JoinColumn(name = "parent_id")
  private Parent parent;

  @OneToMany(
    mappedBy = "child2",
    cascade = CascadeType.ALL,
    orphanRemoval = true
  )
  private Set<ChildOfChild2> childOfChild2= new HashSet<>();

  //Constructors, getters and setters removed for brevity

 }

Upvotes: 3

Views: 1546

Answers (1)

SternK
SternK

Reputation: 13041

You can try to use something like this:

entityManager.createQuery("select p from Parent p " +
   "left join fetch p.child1 child1_ " +
   "left join fetch child1_.childOfChild1 " +
   "left join fetch p.child2 child2_ " +
   "left join fetch child2_.childOfChild2 " +
   "where p.parentId = :parentId", Parent.class);

And look at this

Upvotes: 2

Related Questions