0

I'm using @OneToMany feature, with FetchType.EAGER set. But JPA (through EclipseLink) keep making one sub request for each sub object in my list. I really dont get why. I follow many thread I found, but cant make this select work in one single request.

Also, I retrive my object with CriteriaBuilder, CriteriaQuery and some Predicate. This may be an issue ? Anyway, all this filter are only use for the top lvl classes. I still want the lower one to be fetched as well.

My entities look like :

@Entity
@Table(name = "mainTable")
public class MainTable extends SqlEntity {

    @OneToMany(fetch = FetchType.EAGER)
    private List<MainLocation> locations = new ArrayList<MainLocation>();
    ...
}

@Entity
@Table(name = "mainLocation")
public class MainLocation extends SqlEntity {

    @OneToMany(fetch = FetchType.EAGER)
    private List<MainDetail> details = new ArrayList<MainDetail>();
    ...
}

@Entity
@Table(name = "mainDetail")
public class MainDetail extends SqlEntity {
    ...
}
  • Depends also on your provider, is it Hibernate? – pdem Apr 03 '18 at 12:25
  • You should keep things lazy. You can convert from lazy to eager, but you can't convert in the other way. Then you'd need a `JOIN FETCH` (that's in JPQL), which should work with criteria something like this: https://stackoverflow.com/questions/17306655/using-the-jpa-criteria-api-can-you-do-a-fetch-join-that-results-in-only-one-joi – Kayaman Apr 03 '18 at 12:31
  • @pdem : Using EclipseLink v2.5.1, can upgrad if needed. I also try with Hibernate, same behavior. Kayaman : The issue is, this generate hundred, if not more, request and make a simple request really too slow. I have to wait around 1~2 minute where the same in SQL with join take only 250ms Also, I would like to not have to rewrite all the apps using this with JPQL, if possible... – Mickey Book Apr 03 '18 at 13:03
  • In hibernate you can use @Fetch(FetchMode.JOIN) but this is hibernate specific. Also prefer using Set instead of List with hibernate. – pdem Apr 03 '18 at 13:05
  • It's normal behaviour. You need to go to implementation specific things if you want better control, such as described here: https://stackoverflow.com/questions/25821718/difference-between-fetchmode-and-fetchtype but like I said, don't make them eager. It's wrong and you'll be sorry. See the link in my first comment for how to do it properly. – Kayaman Apr 03 '18 at 13:06
  • @pdem : Thanks, I'll give a try soon – Mickey Book Apr 03 '18 at 13:07
  • @kayaman : I don't want a "better" control, I just want every data in once. I need all this data when I do this call, otherwise I would not have put Eager key word here. And as the app is curently not working beacause of this lazy behavior, I can only be happy. Anyway, I check your second link with Hibernate scpecifique code as pdem sugest, and it work perfectly ! But I still doesn't understand why my JPA version doesn't. Only one SQL request for all the data using left outer join – Mickey Book Apr 03 '18 at 13:30
  • I didn't recommend going implementation specific. I just said that you can't do it with JPA. What you can do with JPA is eager joins at fetch time, as I explained in my first comment. I've given you instructions on how to do it right, you can ignore them if you want, but that's your choice. – Kayaman Apr 03 '18 at 13:56
  • @kayaman : oh no, I didn't ignore them at all. I just already found this thread and even try. But I think this is not the thing I'm looking for. If I get it right, this would let me chose each sub object iI would join for every request. But in this "specifique" case, I just want everything, working with some sort and filters. Anyway, I try many things, and Hibernat + using Set did it for me With the same request and EclipseLink, it still make many sub request. So I guess Hibernate was the anwser. If you still think I miss understand something, feel free to let me know, I'm here to learn :) – Mickey Book Apr 03 '18 at 14:34
  • Well I already told you what to do. You decided to do a different thing. It doesn't matter really, you'll get it eventually. – Kayaman Apr 03 '18 at 14:36
  • @Kayaman aaand, you was 100% right! In fact, I did it as I test it, then I forgot it was still here, in some compiled Jar (removed from source code)... What a surpise when I rebuild my soft, and nothing was working anymore. I _have_ to do some root.join/fetch to make it work. But, still not work with EclipseLink, so I also have to use Hibernate for some reason. Thanks again! – Mickey Book Apr 03 '18 at 20:37
  • No problem, glad you got it working. I'm not at all familiar with EclipseLink, but Hibernate is pretty much the de facto standard with JPA. If you can switch to it, that's probably just a good thing. – Kayaman Apr 04 '18 at 05:16

0 Answers0