2


We have a class A that has two levels of nested associations as follows:

@Entity
@NamedQuery("select a from A JOIN FETCH b");
public class A {
     @OneToOne(cascade = CascadeType.ALL, optional = true)
     @JoinColumn(name = "XXX")
     private B b;
}

@Entity
public class B {
     @OneToMany(cascade = CascadeType.ALL, orphanRemoval = true)
     @JoinColumn(name = "XXX")
     @Fetch(FetchMode.SUBSELECT)
     private List<B> details = new ArrayList<>(); 
}

@Entity
public class C {
  ...
}

Now for a report query we are fetching all A records, so I do a two-step query first I use pagination using setMaxResults and setFirstResult and then use the IDs of fetched objects to fire the second query where I want the entire object graph for the paginated object IDs. Now since Hibernate does not seem to allow to SUBSELECT for OneToOne, to fetch records of B, I resorted to JOIN FETCH (would prefer SUBSELECT here also if anyone knows how to do it, please share) but table C is much larger and I want to use SUBSELECT than join. Without the SUBSELECT, it fires many queries but uses the single IN parameter I specify and passes. But with SUBSELECT, it seems to expect the same IN parameter again,

as in real SQL queries are like

select a.id from a limit ?  (fetch IDs by pagination)
select a.*, b.* from a inner join b on a.b_id=b.id where a.id in (?, ?)
select c.* from c where c.id in (select c_id from b where b.id in (Select b_id from a where id in (?, ?)))  - (this is fired by the SUBSELECT,  how to resend same named parameter say :ids a second time for this scenario?)

My code is like this:

List<Long> ids = fetchIds(startPos, maxRecords);
TypedQuery<A> query =em.createNamedQuery(A.NAMED_QUERY, A.class);
query.setParameter("ids", ids);

Assume that the fetchIds fetches the IDs in first step by pagination as described (no issues there).

Thanks,
Paddy

Paddy
  • 3,472
  • 5
  • 29
  • 48

0 Answers0